diff options
author | Christopher Faylor <me@cgf.cx> | 2004-12-23 14:57:08 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-12-23 14:57:08 +0000 |
commit | 4ee52924a61bdb2fd8ce7b64d111cf7df4d19fe3 (patch) | |
tree | 18464135531157edc28ecc4f73a7210511638611 /winsup/cygwin/cygthread.cc | |
parent | 3993374d4ee8a081056fad98ebed90975970ccee (diff) | |
download | cygnal-4ee52924a61bdb2fd8ce7b64d111cf7df4d19fe3.tar.gz cygnal-4ee52924a61bdb2fd8ce7b64d111cf7df4d19fe3.tar.bz2 cygnal-4ee52924a61bdb2fd8ce7b64d111cf7df4d19fe3.zip |
* cygthread.cc (cygthread::stub): Detect if thread function wants to release
itself here, to avoid a race.
(cygthread::release): Clear more stuff. Add a diagnostic for an internal
error.
* cygthread.h (auto_release): New function.
* pinfo.h (pinfo::remember): Add an argument to denote whether child is
detached.
* fork.cc (fork_parent): Reflect change in arguments to pinfo::remember.
* pinfo.cc (_pinfo::exit): Signal exit more forcibly.
(proc_waiter): Use cygthread::auto_release to signify that cygthread::stub
should release the thread. This should avoid a race.
(pinfo::alert_parent): Don't signify an error when wr_proc_pipe == NULL.
* sigproc.cc (proc_subproc): Add support for PROC_DETACHED_CHILD.
* sigproc.h: Ditto.
* spawn.cc (spawn_guts): Specify whether child is detached or not when calling
pinfo::remember.
Diffstat (limited to 'winsup/cygwin/cygthread.cc')
-rw-r--r-- | winsup/cygwin/cygthread.cc | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 949f4716c..bca2b28f8 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -69,13 +69,21 @@ cygthread::stub (VOID *arg) info->func (info->arg == cygself ? info : info->arg); /* ...so the above should always return */ + /* If stack_ptr is NULL, the above function has set that to indicate + that it doesn't want to alert anyone with a SetEvent and should + just be marked as no longer inuse. Hopefully the function knows + that it is doing. */ + if (!info->func) + info->release (false); + else + { #ifdef DEBUGGING - info->func = NULL; // catch erroneous activation - info->__oldname = info->__name; + info->func = NULL; // catch erroneous activation + info->__oldname = info->__name; #endif - info->__name = NULL; - if (info->inuse) - SetEvent (info->ev); + info->__name = NULL; + SetEvent (info->ev); + } } switch (WaitForSingleObject (info->thread_sync, INFINITE)) { @@ -231,7 +239,13 @@ cygthread::release (bool nuke_h) __oldname = __name; __name = NULL; stack_ptr = NULL; - (void) InterlockedExchange (&inuse, 0); /* No longer in use */ + func = NULL; + if (!InterlockedExchange (&inuse, 0)) +#ifdef DEBUGGING + api_fatal ("released a thread that was not inuse"); +#else + system_printf ("released a thread that was not inuse"); +#endif } /* Forcibly terminate a thread. */ |