From a4c4ef181236cd0ad81e34dfaf3e6f9c08e12a41 Mon Sep 17 00:00:00 2001 From: davygrvy Date: Tue, 20 Jan 2004 05:18:22 +0000 Subject: * win/tclWinPipe.c (Tcl_WaitPid): Fixed a thread-safety problem with the process list. The delayed cut operation after the wait was going stale by being outside the list lock. It now cuts within the lock and does a locked splice for when it needs to instead. [Bug 859820] --- win/tclWinPipe.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4edf214..93d4a17 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinPipe.c,v 1.39 2003/12/24 04:18:23 davygrvy Exp $ + * RCS: @(#) $Id: tclWinPipe.c,v 1.40 2004/01/20 05:18:22 davygrvy Exp $ */ #include "tclWinInt.h" @@ -906,6 +906,8 @@ TclpGetPid( { ProcInfo *infoPtr; + PipeInit(); + Tcl_MutexLock(&pipeMutex); for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { if (infoPtr->hProcess == (HANDLE) pid) { @@ -2485,7 +2487,7 @@ Tcl_WaitPid( int *statPtr, int options) { - ProcInfo *infoPtr, **prevPtrPtr; + ProcInfo *infoPtr = NULL, **prevPtrPtr; DWORD flags; Tcl_Pid result; DWORD ret, exitCode; @@ -2502,7 +2504,7 @@ Tcl_WaitPid( } /* - * Find the process on the process list. + * Find the process and cut it from the process list. */ Tcl_MutexLock(&pipeMutex); @@ -2510,6 +2512,7 @@ Tcl_WaitPid( for (infoPtr = procList; infoPtr != NULL; prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { if (infoPtr->hProcess == (HANDLE) pid) { + *prevPtrPtr = infoPtr->nextPtr; break; } } @@ -2539,6 +2542,13 @@ Tcl_WaitPid( if (ret == WAIT_TIMEOUT) { *statPtr = 0; if (options & WNOHANG) { + /* + * Re-insert this infoPtr back on the list. + */ + Tcl_MutexLock(&pipeMutex); + infoPtr->nextPtr = procList; + procList = infoPtr; + Tcl_MutexUnlock(&pipeMutex); return 0; } else { result = 0; @@ -2601,11 +2611,10 @@ Tcl_WaitPid( } /* - * Remove the process from the process list and close the process handle. + * Officially close the process handle. */ CloseHandle(infoPtr->hProcess); - *prevPtrPtr = infoPtr->nextPtr; ckfree((char*)infoPtr); return result; -- cgit v0.12