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:
authorChristopher Faylor <me@cgf.cx>2003-08-20 06:31:26 +0400
committerChristopher Faylor <me@cgf.cx>2003-08-20 06:31:26 +0400
commit5f31e0f30557788f0f451fd69fbc70a89c271c18 (patch)
tree1b3763c8d947acb63beddda0bc7e4c610b1fed96 /winsup/cygwin
parent6ac844b5e3ef1c50a6faeac37abd23f9b8b8fe6d (diff)
* exceptions.cc (pending_signals): Remove unneeded declaration.
* sigproc.cc (pending_signals): Make static. (wait_sig): Use defined values rather than integers for rc. Never scan both todo arrays as this could cause hangs if signals arrive from two different sources. Rename saw_pending_signals to saw_failed_interrupt. Exit loop when signal found. Enter low-priority sleep, if necessary, after finished signalling completion. Set pending_signals when blocked (from Pierre Humblet).
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/exceptions.cc1
-rw-r--r--winsup/cygwin/sigproc.cc56
3 files changed, 37 insertions, 31 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3b49b384c..83a902e9c 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,16 @@
2003-08-19 Christopher Faylor <cgf@redhat.com>
+ * exceptions.cc (pending_signals): Remove unneeded declaration.
+ * sigproc.cc (pending_signals): Make static.
+ (wait_sig): Use defined values rather than integers for rc. Never scan
+ both todo arrays as this could cause hangs if signals arrive from two
+ different sources. Rename saw_pending_signals to saw_failed_interrupt.
+ Exit loop when signal found. Enter low-priority sleep, if necessary,
+ after finished signalling completion. Set pending_signals when blocked
+ (from Pierre Humblet).
+
+2003-08-19 Christopher Faylor <cgf@redhat.com>
+
* signal.cc (sigpending): Move.
* sigproc.cc (sigpending): To here.
(getlocal_sigtodo): Return process-local signal array.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index dea7c8b3e..537f55e99 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -591,7 +591,6 @@ handle_sigsuspend (sigset_t tempmask)
}
extern DWORD exec_exit; // Possible exit value for exec
-extern int pending_signals;
extern "C" {
static void
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 4ac1d8e4e..f9fed06ec 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -123,7 +123,7 @@ muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
DWORD NO_COPY sigtid = 0; // ID of the signal thread
-int NO_COPY pending_signals = 0; // TRUE if signals pending
+static bool NO_COPY pending_signals = false; // true if signals pending
/* Functions
*/
@@ -1042,6 +1042,9 @@ talktome ()
pids[i]->commune_recv ();
}
+#define RC_MAIN 0
+#define RC_NONMAIN 1
+#define RC_NOSYNC 2
/* Process signals by waiting for a semaphore to become signaled.
* Then scan an in-memory array representing queued signals.
* Executes in a separate thread.
@@ -1141,25 +1144,24 @@ wait_sig (VOID *self)
LONG **start_todo, **end_todo;
switch (rc)
{
- case 0:
+ case RC_MAIN:
+ case RC_NONMAIN:
start_todo = todos;
end_todo = todos;
break;
- case 1:
+ case RC_NOSYNC:
+ default: // silence compiler warning
start_todo = todos + 1;
end_todo = todos + 1;
- default:
- start_todo = todos;
- end_todo = todos + 1;
+ break;
}
/* A sigcatch semaphore has been signaled. Scan the sigtodo
* array looking for any unprocessed signals.
*/
- pending_signals = -1;
- bool saw_pending_signals = false;
- bool saw_sigchld = false;
- for (LONG **todo = start_todo; todo <= end_todo; todo++)
+ pending_signals = false;
+ bool saw_failed_interrupt = false;
+ for (LONG **todo = todos; todo <= end_todo; todo++)
for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
{
LONG x = InterlockedDecrement (*todo + sig);
@@ -1168,10 +1170,7 @@ wait_sig (VOID *self)
else if (x >= 0)
{
if (x > 0)
- pending_signals = 1;
-
- if (sig == SIGCHLD)
- saw_sigchld = true;
+ pending_signals = true; /* semaphore should already be armed */
if (sig > 0 && sig != SIGKILL && sig != SIGSTOP &&
(sigismember (&myself->getsigmask (), sig) ||
@@ -1180,6 +1179,7 @@ wait_sig (VOID *self)
{
sigproc_printf ("signal %d blocked", sig);
InterlockedIncrement (*todo + sig);
+ pending_signals = true; // FIXME: This will cause unnecessary sig_dispatch_pending spins
}
else
{
@@ -1206,41 +1206,37 @@ wait_sig (VOID *self)
if (!sig_handle (sig))
{
sigproc_printf ("couldn't send signal %d", sig);
- low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */
- saw_pending_signals = true;
+ pending_signals = saw_failed_interrupt = true;
ReleaseSemaphore (sigcatch_nosync, 1, NULL);
- InterlockedIncrement (*todo + sig);
+ InterlockedIncrement (myself->getsigtodo (sig));
}
- break;
}
}
+
+ if (sig == SIGCHLD)
+ proc_subproc (PROC_CLEARWAIT, 0);
+ goto out;
}
}
- if (saw_pending_signals)
- pending_signals = 1;
- else if (pending_signals < 0)
- pending_signals = 0;
-
- if (saw_sigchld)
- proc_subproc (PROC_CLEARWAIT, 0);
-
+ out:
/* Signal completion of signal handling depending on which semaphore
- * woke up the WaitForMultipleObjects above.
- */
+ woke up the WaitForMultipleObjects above. */
switch (rc)
{
- case 0:
+ case RC_MAIN:
SetEvent (sigcomplete_main);
sigproc_printf ("set main thread completion event");
break;
- case 1:
+ case RC_NONMAIN:
ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
break;
default:
/* Signal from another process. No need to synchronize. */
break;
}
+ if (saw_failed_interrupt)
+ low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other thread will be waking up soon. */
sigproc_printf ("looping");
}