summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorferrieux <ferrieux@users.sourceforge.net>2012-07-25 09:57:03 (GMT)
committerferrieux <ferrieux@users.sourceforge.net>2012-07-25 09:57:03 (GMT)
commitbfff3b18a0b4f5b7cfa4e431e3901a149016e1c1 (patch)
tree2e1a6800e7ec4046eed6b2937f7e907553a41b22
parent435ea67469544d205ef22229b350e6dca6917357 (diff)
downloadtcl-bfff3b18a0b4f5b7cfa4e431e3901a149016e1c1.zip
tcl-bfff3b18a0b4f5b7cfa4e431e3901a149016e1c1.tar.gz
tcl-bfff3b18a0b4f5b7cfa4e431e3901a149016e1c1.tar.bz2
[Bug 3547994]: Abandon the synchronous Windows pipe driver to its fate when needed to honour TIP#398.
-rw-r--r--ChangeLog5
-rw-r--r--win/tclWinPipe.c26
2 files changed, 27 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 1175302..0eb99af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-25 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * win/tclWinPipe.c: [Bug 3547994]: Abandon the synchronous Windows
+ pipe driver to its fate when needed to honour TIP#398.
+
2012-07-23 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
* generic/tclIO.c: [Bug 3545365]: Never try a bg-flush on a dead
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index cc696a2..f36f797 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -1875,12 +1875,26 @@ PipeClose2Proc(
&& (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
@@ -2945,6 +2959,10 @@ PipeWriterThread(
* an error, so exit.
*/
+ if (waitResult == WAIT_OBJECT_0) {
+ SetEvent(infoPtr->writable);
+ }
+
break;
}