summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-06-03 19:57:31 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-06-03 19:57:31 (GMT)
commit3c491801cbe73e305c0024a9b5bd80b7e474cabf (patch)
tree48debe3a1e9df42db2e038d0180766f3b4d9c154
parentea994aa1957bd3faea8f4cdf2ae290d102ae1fe8 (diff)
parent2925ec375b371070e4955cfa6503a8dc4de45f68 (diff)
downloadtcl-3c491801cbe73e305c0024a9b5bd80b7e474cabf.zip
tcl-3c491801cbe73e305c0024a9b5bd80b7e474cabf.tar.gz
tcl-3c491801cbe73e305c0024a9b5bd80b7e474cabf.tar.bz2
merge fork of 8.5 branch
-rw-r--r--generic/tclIO.c39
-rw-r--r--tests/io.test6
-rw-r--r--unix/tclUnixPipe.c4
-rw-r--r--win/tclWinSock.c20
4 files changed, 42 insertions, 27 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 1c4a5b3..ed94bfe 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -2694,18 +2694,11 @@ FlushChannel(
(chanPtr->typePtr->watchProc)(chanPtr->instanceData,
statePtr->interestMask);
} else {
-
- /*
- * When we are calledFromAsyncFlush, that means a writable
- * state on the channel triggered the call, so we should be
- * able to write something. Either we did write something
- * and wroteSome should be set, or there was nothing left to
- * write in this call, and we've completed the BG flush.
- * These are the two cases above. If we get here, that means
- * there is some kind failure in the writable event machinery.
- */
-
- assert(!calledFromAsyncFlush);
+ /* TODO: If code reaches this point, it means a writable
+ * event is being handled on the channel, but the channel
+ * could not in fact be written to. This ought not happen,
+ * but Unix pipes appear to act this way (see io-53.4).
+ * Also can imagine broken reflected channels. */
}
}
@@ -3212,11 +3205,18 @@ Tcl_Close(
stickyError = 0;
- if ((statePtr->encoding != NULL)
- && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
- && (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
- statePtr->outputEncodingFlags |= TCL_ENCODING_END;
- if (WriteChars(chanPtr, "", 0) < 0) {
+ if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL)
+ && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) {
+
+ int code = CheckChannelErrors(statePtr, TCL_WRITABLE);
+
+ if (code == 0) {
+ statePtr->outputEncodingFlags |= TCL_ENCODING_END;
+ code = WriteChars(chanPtr, "", 0);
+ statePtr->outputEncodingFlags &= ~TCL_ENCODING_END;
+ statePtr->outputEncodingFlags |= TCL_ENCODING_START;
+ }
+ if (code < 0) {
stickyError = Tcl_GetErrno();
}
@@ -7646,8 +7646,9 @@ Tcl_NotifyChannel(
*/
if (GotFlag(statePtr, BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) {
- FlushChannel(NULL, chanPtr, 1);
- mask &= ~TCL_WRITABLE;
+ if (0 == FlushChannel(NULL, chanPtr, 1)) {
+ mask &= ~TCL_WRITABLE;
+ }
}
/*
diff --git a/tests/io.test b/tests/io.test
index 2296986..f1248b9 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -7120,12 +7120,17 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven
for {set x 0} {$x < 12} {incr x} {
append big $big
}
+# file delete $path(test1)
file delete $path(pipe)
set f1 [open $path(pipe) w]
puts $f1 {
puts ready
fcopy stdin stdout -command { set x }
vwait x
+# set f [open $path(test1) w]
+# fconfigure $f -translation lf
+# puts $f "done"
+# close $f
}
close $f1
set f1 [open "|[list [interpreter] $path(pipe)]" r+]
@@ -7133,6 +7138,7 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven
fconfigure $f1 -blocking 0
puts $f1 $big
flush $f1
+ after 500
set result ""
fileevent $f1 read [namespace code {
append result [read $f1 1024]
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index 57be08f..d0a5e53 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -1125,7 +1125,7 @@ PipeWatchProc(
if (psPtr->inFile) {
newmask = mask & (TCL_READABLE | TCL_EXCEPTION);
if (newmask) {
- Tcl_CreateFileHandler(GetFd(psPtr->inFile), newmask,
+ Tcl_CreateFileHandler(GetFd(psPtr->inFile), mask,
(Tcl_FileProc *) Tcl_NotifyChannel,
(ClientData) psPtr->channel);
} else {
@@ -1135,7 +1135,7 @@ PipeWatchProc(
if (psPtr->outFile) {
newmask = mask & (TCL_WRITABLE | TCL_EXCEPTION);
if (newmask) {
- Tcl_CreateFileHandler(GetFd(psPtr->outFile), newmask,
+ Tcl_CreateFileHandler(GetFd(psPtr->outFile), mask,
(Tcl_FileProc *) Tcl_NotifyChannel,
(ClientData) psPtr->channel);
} else {
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index e18a3dd..8f565b9 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -1239,13 +1239,17 @@ WaitForSocketEvent(
/*
* Reset WSAAsyncSelect so we have a fresh set of events pending.
+ * Don't do that if we are waiting for a connect as we may miss
+ * a connect (bug 336441ed59).
*/
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT,
- (LPARAM) infoPtr);
-
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
- (LPARAM) infoPtr);
+ if ( 0 == (events & FD_CONNECT) ) {
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT,
+ (LPARAM) infoPtr);
+
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
+ (LPARAM) infoPtr);
+ }
while (1) {
if (infoPtr->lastError) {
@@ -2409,11 +2413,15 @@ SocketProc(
case SOCKET_SELECT:
infoPtr = (SocketInfo *) lParam;
if (wParam == SELECT) {
+ /*
+ * Start notification by windows messages on socket events
+ */
+
WSAAsyncSelect(infoPtr->socket, hwnd,
SOCKET_MESSAGE, infoPtr->selectEvents);
} else {
/*
- * Clear the selection mask
+ * UNSELECT: Clear the selection mask
*/
WSAAsyncSelect(infoPtr->socket, hwnd, 0, 0);