diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 15e490211..1f24c390c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2015-10-23 Corinna Vinschen + + * cygtls.cc (_cygtls::remove): Call remove_pending_sigs. + * cygtls.h (_cygtls::remove_pending_sigs): Declare. + * sigproc.cc (pending_signals::clear): Define new method taking a + _cygtls pointer argument. Drop pending signals for that thread. + (_cygtls::remove_pending_sigs): Call pending_signals::clear for this + thread. + 2015-10-22 Corinna Vinschen * common.din (aligned_alloc): Export. diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index cb8c24e8f..c94578ffa 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -187,6 +187,7 @@ _cygtls::remove (DWORD wait) /* FIXME: Need some sort of atthreadexit function to allow things like select to control this themselves. */ + remove_pending_sigs (); if (signal_arrived) { HANDLE h = signal_arrived; diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index c8615af70..b386b989d 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -267,6 +267,7 @@ public: void handle_SIGCONT (); private: void __reg3 call2 (DWORD (*) (void *, void *), void *, void *); + void remove_pending_sigs (); /*gentls_offsets*/ }; #pragma pack(pop) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 9f261c9b3..387a71a69 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -79,7 +79,8 @@ public: void add (sigpacket&); bool pending () {retry = true; return !!start.next;} void clear (int sig) {sigs[sig].si.si_signo = 0;} - friend void __reg1 sig_dispatch_pending (bool);; + void clear (_cygtls *tls); + friend void __reg1 sig_dispatch_pending (bool); friend void WINAPI wait_sig (VOID *arg); friend void sigproc_init (); }; @@ -397,6 +398,23 @@ sig_clear (int sig) sigq.clear (sig); } +/* Clear pending signals of specific thread. Called from + _cygtls::remove_pending_sigs. */ +void +pending_signals::clear (_cygtls *tls) +{ + for (int sig = 0; sig < NSIG + 1; ++sig) + if (sigs[sig].sigtls == tls) + clear (sig); +} + +/* Clear pending signals of specific thread. Called from _cygtls::remove */ +void +_cygtls::remove_pending_sigs () +{ + sigq.clear (this); +} + extern "C" int sigpending (sigset_t *mask) {