diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-03-29 09:12:13 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-03-29 09:12:13 +0000 |
commit | 4ec65c80afbc9f513b4f7e5148f200cb807e6f88 (patch) | |
tree | 901d3aae8f58102aba605c3ac3414ed69eaa8562 | |
parent | d5491b0ea06649d59ae9d3bea6772bb40374bc6d (diff) | |
download | newlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.zip newlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.tar.gz newlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.tar.bz2 |
Pull in changes from HEAD
-rw-r--r-- | winsup/cygwin/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 63 |
3 files changed, 37 insertions, 42 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8404c33..1ccbcf1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2013-03-28 Christopher Faylor <me.cygwin2013@cgf.cx> + + * sigproc.cc (pending_signals::retry): Declare new element. + (pending_signals::pending): Force an additional loop through wait_sig + by setting retry whenever this function is called. + (sig_send): Reorganize to wait for SIGHOLD at bottom. Always add + signal to pending queue and work on whole queue rather than just the + one signal. Loop when sigq.retry is set. Fix long-broken check for + SIGCHLD after queued signals. + +2013-03-28 Christopher Faylor <me.cygwin2013@cgf.cx> + + * exceptions.cc (exception::handle): Generalize comment. + 2013-03-09 Christopher Faylor <me.cygwin2013@cgf.cx> * cygtls.h (_cygtls::signal_debugger): Change argument type. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 496b907..44c325c 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -728,7 +728,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void return CYG_EXC_CONTINUE_EXECUTION; } - /* FIXME: Probably should be handled in sigpacket::process */ + /* FIXME: Probably should be handled in signal processing code */ if ((NTSTATUS) e->ExceptionCode == STATUS_ACCESS_VIOLATION) { int error_code = 0; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 3e078de..5721ef4 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -76,11 +76,12 @@ class pending_signals sigpacket *end; sigpacket *prev; sigpacket *curr; + bool retry; public: void reset () {curr = &start; prev = &start;} void add (sigpacket&); void del (); - bool pending () const {return !!start.next;} + bool pending () {retry = true; return !!start.next;} sigpacket *next (); sigpacket *save () const {return curr;} void restore (sigpacket *saved) {curr = saved;} @@ -627,7 +628,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) } } - sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me); + sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, + si.si_signo, its_me); sigset_t pending; if (!its_me) @@ -1231,9 +1233,9 @@ void pending_signals::add (sigpacket& pack) { sigpacket *se; - if (sigs[pack.si.si_signo].si.si_signo) - return; se = sigs + pack.si.si_signo; + if (se->si.si_signo) + return; *se = pack; se->mask = &pack.sigtls->sigmask; se->next = NULL; @@ -1281,18 +1283,17 @@ wait_sig (VOID *) sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p", my_readsig, my_sendsig); - sigpacket pack; - pack.si.si_signo = 0; for (;;) { - if (pack.si.si_signo == __SIGHOLD) - WaitForSingleObject (sig_hold, INFINITE); - DWORD nb; - pack.sigtls = NULL; - if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL)) - break; - + sigpacket pack = {}; + if (sigq.retry) + { + sigq.retry = false; + pack.si.si_signo = __SIGFLUSH; + } + else if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL)) + Sleep (INFINITE); /* Never exit this thread */ if (nb != sizeof (pack)) { system_printf ("short read from signal pipe: %u != %lu", nb, @@ -1340,6 +1341,11 @@ wait_sig (VOID *) case __SIGHOLD: goto loop; break; + default: + if (pack.si.si_signo < 0) + sig_clear (-pack.si.si_signo); + else + sigq.add (pack); case __SIGNOHOLD: case __SIGFLUSH: case __SIGFLUSHFAST: @@ -1349,7 +1355,7 @@ wait_sig (VOID *) int sig = q->si.si_signo; if (sig == __SIGDELETE || q->process () > 0) sigq.del (); - if (sig == __SIGNOHOLD && q->si.si_signo == SIGCHLD) + if (sig == SIGCHLD) clearwait = true; } break; @@ -1373,33 +1379,6 @@ wait_sig (VOID *) system_printf ("WaitForSingleObject(%p) for thread exit returned %u", h, res); } break; - default: - if (pack.si.si_signo < 0) - sig_clear (-pack.si.si_signo); - else - { - int sig = pack.si.si_signo; - // FIXME: REALLY not right when taking threads into consideration. - // We need a per-thread queue since each thread can have its own - // list of blocked signals. CGF 2005-08-24 - if (sigq.sigs[sig].si.si_signo && sigq.sigs[sig].sigtls == pack.sigtls) - sigproc_printf ("signal %d already queued", pack.si.si_signo); - else - { - int sigres = pack.process (); - if (sigres <= 0) - { -#ifdef DEBUGGING2 - if (!sigres) - system_printf ("Failed to arm signal %d from pid %d", pack.si.si_signo, pack.pid); -#endif - sigq.add (pack); // FIXME: Shouldn't add this in !sh condition - } - } - if (sig == SIGCHLD) - clearwait = true; - } - break; } if (clearwait && !have_execed) proc_subproc (PROC_CLEARWAIT, 0); @@ -1409,5 +1388,7 @@ wait_sig (VOID *) sigproc_printf ("signalling pack.wakeup %p", pack.wakeup); SetEvent (pack.wakeup); } + if (pack.si.si_signo == __SIGHOLD) + WaitForSingleObject (sig_hold, INFINITE); } } |