* cygtls.h (_cygtls::create_signal_arrived): New function.

(_cygtls::set_signal_arrived): Lock creation of signal_arrived.
* cygwait.cc (cancelable_wait): Ignore signal_arrived event if _my_tls 'sig'
element does not exist.
* exceptions.cc (_cygtls::interrupt_setup): Create signal_arrived if recipient
thread has not created it.
This commit is contained in:
Christopher Faylor 2012-08-15 18:50:44 +00:00
parent 588b40e260
commit 879f3ad5ee
4 changed files with 36 additions and 7 deletions

View File

@ -1,3 +1,12 @@
2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx>
* cygtls.h (_cygtls::create_signal_arrived): New function.
(_cygtls::set_signal_arrived): Lock creation of signal_arrived.
* cygwait.cc (cancelable_wait): Ignore signal_arrived event if _my_tls
'sig' element does not exist.
* exceptions.cc (_cygtls::interrupt_setup): Create signal_arrived if
recipient thread has not created it.
2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx> 2012-08-15 Christopher Faylor <me.cygwin2012@cgf.cx>
* gendef: Tighten up whitespace detection. * gendef: Tighten up whitespace detection.

View File

@ -235,6 +235,10 @@ public:
void lock () __attribute__ ((regparm (1))); void lock () __attribute__ ((regparm (1)));
void unlock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1)));
bool locked () __attribute__ ((regparm (1))); bool locked () __attribute__ ((regparm (1)));
void create_signal_arrived ()
{
signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
}
void set_signal_arrived (bool setit, HANDLE& h) void set_signal_arrived (bool setit, HANDLE& h)
{ {
if (!setit) if (!setit)
@ -242,7 +246,11 @@ public:
else else
{ {
if (!signal_arrived) if (!signal_arrived)
signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL); {
lock ();
create_signal_arrived ();
unlock ();
}
h = signal_arrived; h = signal_arrived;
signal_waiting = true; signal_waiting = true;
} }

View File

@ -79,10 +79,18 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
res = WAIT_TIMEOUT; res = WAIT_TIMEOUT;
else if (res != sig_n) else if (res != sig_n)
/* all set */; /* all set */;
else if (is_cw_sig_eintr) else
res = WAIT_SIGNALED; /* caller will deal with signals */ {
else if (_my_tls.call_signal_handler ()) _my_tls.lock ();
continue; int sig = _my_tls.sig;
_my_tls.unlock ();
if (!sig)
continue;
if (is_cw_sig_eintr)
res = WAIT_SIGNALED; /* caller will deal with signals */
else if (_my_tls.call_signal_handler ())
continue;
}
break; break;
} }

View File

@ -796,8 +796,12 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
this->sig = sig; // Should always be last thing set to avoid a race this->sig = sig; // Should always be last thing set to avoid a race
if (incyg && signal_arrived) if (incyg)
SetEvent (signal_arrived); {
if (!signal_arrived)
create_signal_arrived ();
SetEvent (signal_arrived);
}
proc_subproc (PROC_CLEARWAIT, 1); proc_subproc (PROC_CLEARWAIT, 1);
sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, sig); sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, sig);