Tcl Source Code

Artifact [cf79848a6b]
Login

Artifact cf79848a6bd7d83d73a9fcca645b1fd4ab0d0177:

Attachment "winpipe.patch" to ticket [3547994fff] added by ferrieux 2012-07-25 04:09:18.
Index: win/tclWinPipe.c
===================================================================
--- win/tclWinPipe.c
+++ win/tclWinPipe.c
@@ -1873,16 +1873,30 @@
     }
     if ((!flags || flags & TCL_CLOSE_WRITE)
 	    && (pipePtr->writeFile != NULL)) {
 	if (pipePtr->writeThread) {
 	    /*
-	     * Wait for the writer thread to finish the current buffer, then
-	     * terminate the thread and close the handles. If the channel is
-	     * nonblocking, there should be no pending write operations.
+	     * Wait for the  writer thread to finish the  current buffer, then
+	     * terminate the thread  and close the handles. If  the channel is
+	     * nonblocking but blocked during  exit, bail out since the worker
+	     * thread is not interruptible and we want TIP#398-fast-exit.
 	     */
+	    if (TclInExit()
+		&& (pipePtr->flags & PIPE_ASYNC)) {
 
-	    WaitForSingleObject(pipePtr->writable, INFINITE);
+		/* give it a chance to leave honorably */
+		SetEvent(pipePtr->stopWriter);
+
+		if (WaitForSingleObject(pipePtr->writable, 0) == WAIT_TIMEOUT) {
+		    return EAGAIN;
+		}
+
+	    } else {
+
+		WaitForSingleObject(pipePtr->writable, INFINITE);
+
+	    }
 
 	    /*
 	     * The thread may already have closed on it's own. Check its exit
 	     * code.
 	     */
@@ -2942,10 +2956,14 @@
 	if (waitResult != (WAIT_OBJECT_0 + 1)) {
 	    /*
 	     * The start event was not signaled. It might be the stop event or
 	     * an error, so exit.
 	     */
+
+	    if (waitResult == WAIT_OBJECT_0) {
+		SetEvent(infoPtr->writable);
+	    }
 
 	    break;
 	}
 
 	buf = infoPtr->writeBuf;