Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog10
-rw-r--r--winsup/cygwin/sigproc.cc63
2 files changed, 32 insertions, 41 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8fb699363..1ccbcf1ef 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,15 @@
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>
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index b49ba4b5e..a38ff0251 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: %d != %d", 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);
}
}