Index: cygtls.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/cygtls.h,v retrieving revision 1.19 diff -u -p -r1.19 cygtls.h --- cygtls.h 9 Mar 2004 01:24:08 -0000 1.19 +++ cygtls.h 12 Mar 2004 01:48:21 -0000 @@ -96,7 +96,7 @@ struct _cygtls int saved_errno; int sa_flags; sigset_t oldmask; - sigset_t newmask; + sigset_t deltamask; HANDLE event; int *errno_addr; unsigned initialized; Index: gendef =================================================================== RCS file: /cvs/src/src/winsup/cygwin/gendef,v retrieving revision 1.15 diff -u -p -r1.15 gendef --- gendef 9 Mar 2004 01:24:08 -0000 1.15 +++ gendef 12 Mar 2004 01:48:22 -0000 @@ -190,15 +190,13 @@ _sigdelayed: movl %fs:4,%ebx incl $tls::incyg(%ebx) pushl $tls::saved_errno(%ebx) # saved errno -3: pushl $tls::oldmask(%ebx) # oldmask + call _set_process_mask_delta + pushl %eax # oldmask pushl $tls::sig(%ebx) # signal argument pushl \$_sigreturn call _reset_signal_arrived\@0 pushl $tls::func(%ebx) # signal func - pushl $tls::newmask(%ebx) # newmask - eaten by set_process_mask - - call _set_process_mask\@4 cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal? jnz 4f #yes. Callee clears signal number movl \$0,$tls::sig(%ebx) # zero the signal number as a Index: exceptions.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/exceptions.cc,v retrieving revision 1.210 diff -u -p -r1.210 exceptions.cc --- exceptions.cc 9 Mar 2004 01:24:08 -0000 1.210 +++ exceptions.cc 12 Mar 2004 01:48:24 -0000 @@ -594,8 +594,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 (); @@ -605,8 +604,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; } @@ -696,8 +696,7 @@ _cygtls::interrupt_setup (int sig, void 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 @@ -926,6 +925,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 @@ -1178,9 +1198,8 @@ _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);