diff options
author | Christopher Faylor <me@cgf.cx> | 2004-12-22 16:59:03 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-12-22 16:59:03 +0000 |
commit | 9bc36097c9a1aaeb2665a5bb28c4b84246970f60 (patch) | |
tree | dbda810383fea9fecd5c4538af0991ab1e879e65 /winsup | |
parent | 9c0d960d7fd60493bc5336061bb65ba02f8dbdbe (diff) | |
download | newlib-9bc36097c9a1aaeb2665a5bb28c4b84246970f60.zip newlib-9bc36097c9a1aaeb2665a5bb28c4b84246970f60.tar.gz newlib-9bc36097c9a1aaeb2665a5bb28c4b84246970f60.tar.bz2 |
* pinfo.cc (proc_waiter): Zero wait_thread in child to avoid races with process
termination.
* cygthread.cc (cygthread::terminate): Clumsily detect when h has gone away and
attempt no further action.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 7 | ||||
-rw-r--r-- | winsup/cygwin/cygthread.cc | 17 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 1 |
3 files changed, 24 insertions, 1 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 88148bf..364f8c3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,12 @@ 2004-12-22 Christopher Faylor <cgf@timesys.com> + * pinfo.cc (proc_waiter): Zero wait_thread in child to avoid races with + process termination. + * cygthread.cc (cygthread::terminate): Clumsily detect when h has gone away + and attempt no further action. + +2004-12-22 Christopher Faylor <cgf@timesys.com> + * cygthread.h (cygthread::release): Just declare here. * cygthread.cc (cygthread::release): Define here. Use InterlockedExchange to set inuse or suffer potential races. diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index d20bf68..80fc5e0 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -226,18 +226,33 @@ cygthread::release () void cygthread::terminate_thread () { + /* FIXME: The if (!h) stuff below should be handled better. The + problem is that terminate_thread could be called while a thread + is terminating and either the thread could be handling its own + release or, if this is being called during exit, some other + thread may be attempting to free up this resource. In the former + case, setting some kind of "I deal with my own exit" type of + flag may be the way to handle this. */ if (!is_freerange) { ResetEvent (*this); ResetEvent (thread_sync); } + if (!h) + return; (void) TerminateThread (h, 0); (void) WaitForSingleObject (h, INFINITE); + if (!h) + return; + CloseHandle (h); - while (!stack_ptr) + while (h && !stack_ptr) low_priority_sleep (0); + if (!h) + return; + MEMORY_BASIC_INFORMATION m; memset (&m, 0, sizeof (m)); (void) VirtualQuery (stack_ptr, &m, sizeof m); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index a26336c..508ed5c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -763,6 +763,7 @@ proc_waiter (void *arg) } sigproc_printf ("exiting wait thread for pid %d", pid); + vchild.wait_thread = NULL; _my_tls._ctinfo->release (); /* return the cygthread to the cygthread pool */ return 0; } |