Clear pending signals targeting exiting thread

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

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-10-23 14:30:40 +02:00
parent 505812d042
commit cf51db8baa
4 changed files with 30 additions and 1 deletions

View File

@ -1,3 +1,12 @@
2015-10-23 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de> 2015-10-22 Corinna Vinschen <corinna@vinschen.de>
* common.din (aligned_alloc): Export. * common.din (aligned_alloc): Export.

View File

@ -187,6 +187,7 @@ _cygtls::remove (DWORD wait)
/* FIXME: Need some sort of atthreadexit function to allow things like /* FIXME: Need some sort of atthreadexit function to allow things like
select to control this themselves. */ select to control this themselves. */
remove_pending_sigs ();
if (signal_arrived) if (signal_arrived)
{ {
HANDLE h = signal_arrived; HANDLE h = signal_arrived;

View File

@ -267,6 +267,7 @@ public:
void handle_SIGCONT (); void handle_SIGCONT ();
private: private:
void __reg3 call2 (DWORD (*) (void *, void *), void *, void *); void __reg3 call2 (DWORD (*) (void *, void *), void *, void *);
void remove_pending_sigs ();
/*gentls_offsets*/ /*gentls_offsets*/
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@ -79,7 +79,8 @@ public:
void add (sigpacket&); void add (sigpacket&);
bool pending () {retry = true; return !!start.next;} bool pending () {retry = true; return !!start.next;}
void clear (int sig) {sigs[sig].si.si_signo = 0;} 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 WINAPI wait_sig (VOID *arg);
friend void sigproc_init (); friend void sigproc_init ();
}; };
@ -397,6 +398,23 @@ sig_clear (int sig)
sigq.clear (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 extern "C" int
sigpending (sigset_t *mask) sigpending (sigset_t *mask)
{ {