aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-12-22 16:59:03 +0000
committerChristopher Faylor <me@cgf.cx>2004-12-22 16:59:03 +0000
commit9bc36097c9a1aaeb2665a5bb28c4b84246970f60 (patch)
treedbda810383fea9fecd5c4538af0991ab1e879e65 /winsup
parent9c0d960d7fd60493bc5336061bb65ba02f8dbdbe (diff)
downloadnewlib-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/ChangeLog7
-rw-r--r--winsup/cygwin/cygthread.cc17
-rw-r--r--winsup/cygwin/pinfo.cc1
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;
}