* 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.
This commit is contained in:
Christopher Faylor
2004-12-23 14:57:08 +00:00
parent 3993374d4e
commit 4ee52924a6
9 changed files with 70 additions and 34 deletions

View File

@ -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. */