* child_info.h (cygheap_exec_info::sigmask): Declare new field.

* cygheap.cc (init_cygheap::find_tls): Rename threadlist_ix -> ix.  Only take
one pass through thread list, looking for eligible threads to signal.  Set a
new param indicating that function has found a sigwait* mask.
* cygheap.h (init_cygheap::find_tls): Reflect new parameter.
* dcrt0.cc (parent_sigmask): New variable.
(child_info_spawn::handle_spawn): Save parent's signal mask here.
(dll_crt0_1): Restore parent's signal mask to tls sigmask as appropriate.  Call
sig_dispatch_pending to flush signal queue when we can finally do something
with signals.
* exceptions.cc (sigpacket::process): Avoid attempting to handle signals if we
haven't finished initializing.  Rely on the fact that find_tls will do mask
checking and don't do it again.  Delete ill-named 'dummy' variable.
* sigproc.cc (cygheap_exec_info::alloc): Save calling thread's signal mask in
new sigmask field.
(wait_sig): Try to debug when WFSO fails and DEBUGGING is defined.
* thread.cc (pthread::set_tls_self_pointer): Make this a true automatic method
rather than inexplicably relying on a thread parameter.
(pthread::thread_init_wrapper): Accommodate set_tls_self_pointer change to
non-static.  Initialize sigmask before setting tid or suffer signal races.
* ehread.h (pthread::set_tls_self_pointer): Make non-static, delete parameter.
This commit is contained in:
Christopher Faylor
2013-03-31 12:35:44 +00:00
parent 4332090c2d
commit 8f8eeb70ba
10 changed files with 111 additions and 62 deletions

View File

@@ -611,37 +611,34 @@ init_cygheap::remove_tls (_cygtls *t, DWORD wait)
}
}
_cygtls *
init_cygheap::find_tls (int sig)
_cygtls __reg3 *
init_cygheap::find_tls (int sig, bool& issig_wait)
{
debug_printf ("sig %d\n", sig);
tls_sentry here (INFINITE);
static int NO_COPY threadlist_ix;
static int NO_COPY ix;
_cygtls *t = _main_tls;
_cygtls *t = NULL;
issig_wait = false;
myfault efault;
if (efault.faulted ())
threadlist[threadlist_ix]->remove (INFINITE);
threadlist[ix]->remove (INFINITE);
else
{
threadlist_ix = -1;
while (++threadlist_ix < (int) nthreads)
if (threadlist[threadlist_ix]->tid
&& sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig))
ix = -1;
while (++ix < (int) nthreads)
if (!threadlist[ix]->tid)
continue;
else if (sigismember (&(threadlist[ix]->sigwait_mask), sig))
{
t = cygheap->threadlist[threadlist_ix];
t = cygheap->threadlist[ix];
issig_wait = true;
goto out;
}
threadlist_ix = -1;
while (++threadlist_ix < (int) nthreads)
if (threadlist[threadlist_ix]->tid
&& !sigismember (&(threadlist[threadlist_ix]->sigmask), sig))
{
t = cygheap->threadlist[threadlist_ix];
break;
}
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
t = cygheap->threadlist[ix];
}
out:
return t;