aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-03-29 09:12:13 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-03-29 09:12:13 +0000
commit4ec65c80afbc9f513b4f7e5148f200cb807e6f88 (patch)
tree901d3aae8f58102aba605c3ac3414ed69eaa8562
parentd5491b0ea06649d59ae9d3bea6772bb40374bc6d (diff)
downloadnewlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.zip
newlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.tar.gz
newlib-4ec65c80afbc9f513b4f7e5148f200cb807e6f88.tar.bz2
Pull in changes from HEAD
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/exceptions.cc2
-rw-r--r--winsup/cygwin/sigproc.cc63
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);
}
}