diff options
author | Christopher Faylor <me@cgf.cx> | 2004-03-12 03:09:28 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-03-12 03:09:28 +0000 |
commit | 9863b78e7bc842bb1b860be12562e1f45b717aef (patch) | |
tree | 2fb5bb2f959861e0bc847526ed21c80936fefaae /winsup/cygwin/exceptions.cc | |
parent | 7ea8e226ee52772fed5215f5231b379db5498bd2 (diff) | |
download | cygnal-9863b78e7bc842bb1b860be12562e1f45b717aef.tar.gz cygnal-9863b78e7bc842bb1b860be12562e1f45b717aef.tar.bz2 cygnal-9863b78e7bc842bb1b860be12562e1f45b717aef.zip |
* cygtls.h (waitq): Declare structure here.
(_cygtls::wq): Declare.
* cygtls.cc (_cygtls::fixup_after_fork): Clear wq.thread_ev to avoid using an
invalid event handle in forked process.
* dcrt0.cc (waitq_storage): Delete.
(threadstuff): Remove waitq_storage.
* perthread.h (per_thread_waitq): Delete.
(waitq_storage): Delete declaration.
* sigproc.cc (sigproc_init): Remove perthread waitq consideration.
* sigproc.h (waitq): Delete declaration.
* wait.cc (wait4): Use _my_tls waitq structure rather than per_thread.
* cygtls.h (_cygtls::newmask): Delete member.
(_cygtls::deltamask): New member.
* gendef (_sigdelayed): Replace the call to set_process_mask by a call to
set_process_mask_delta.
* exceptions.cc (handle_sigsuspend): Do not filter tempmask. Or
SIG_NONMASKABLE in deltamask as a flag.
(_cygtls::interrupt_setup): Set deltamask only.
(set_process_mask_delta): New function.
(_cygtls::call_signal_handler): Replace the first call to set_process_mask by a
call to set_process_mask_delta.
* tlsoffsets.h: Regenerate.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r-- | winsup/cygwin/exceptions.cc | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 21215467b..bf6409a25 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -570,8 +570,7 @@ handle_sigsuspend (sigset_t tempmask) { sigset_t oldmask = myself->getsigmask (); // Remember for restoration - // Let signals we're interested in through. - set_signal_mask (tempmask &= ~SIG_NONMASKABLE, oldmask); + set_signal_mask (tempmask, oldmask); sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); pthread_testcancel (); @@ -581,8 +580,9 @@ handle_sigsuspend (sigset_t tempmask) /* A signal dispatch function will have been added to our stack and will be hit eventually. Set the old mask to be restored when the signal - handler returns. */ + handler returns and indicate its presence by modifying deltamask. */ + _my_tls.deltamask |= SIG_NONMASKABLE; _my_tls.oldmask = oldmask; // Will be restored by signal handler return -1; } @@ -671,8 +671,7 @@ void __stdcall _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) { push ((__stack_t) sigdelayed, false); - oldmask = myself->getsigmask (); - newmask = oldmask | siga.sa_mask | SIGTOMASK (sig); + deltamask = (siga.sa_mask | SIGTOMASK (sig)) & ~SIG_NONMASKABLE; sa_flags = siga.sa_flags; func = (void (*) (int)) handler; saved_errno = -1; // Flag: no errno to save @@ -900,6 +899,27 @@ sighold (int sig) return 0; } +/* Update the signal mask for this process + and return the old mask. + Called from sigdelayed */ +extern "C" sigset_t +set_process_mask_delta () +{ + mask_sync->acquire (INFINITE); + sigset_t newmask, oldmask; + + if (_my_tls.deltamask & SIG_NONMASKABLE) + oldmask = _my_tls.oldmask; /* from handle_sigsuspend */ + else + oldmask = myself->getsigmask (); + newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE; + sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask, + _my_tls.deltamask); + myself->setsigmask (newmask); + mask_sync->release (); + return oldmask; +} + /* Set the signal mask for this process. Note that some signals are unmaskable, as in UNIX. */ extern "C" void __stdcall @@ -1152,14 +1172,13 @@ _cygtls::call_signal_handler () (void) pop (); reset_signal_arrived (); - sigset_t this_oldmask = oldmask; + sigset_t this_oldmask = set_process_mask_delta (); int this_errno = saved_errno; - set_process_mask (newmask); incyg--; sig = 0; sigfunc (thissig); incyg++; - set_process_mask (this_oldmask); + set_signal_mask (this_oldmask); if (this_errno >= 0) set_errno (this_errno); } |