From bfff3b18a0b4f5b7cfa4e431e3901a149016e1c1 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Wed, 25 Jul 2012 09:57:03 +0000 Subject: [Bug 3547994]: Abandon the synchronous Windows pipe driver to its fate when needed to honour TIP#398. --- ChangeLog | 5 +++++ win/tclWinPipe.c | 26 ++++++++++++++++++++++---- 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 + + * 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 * 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; } -- cgit v0.12