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:
authorCorinna Vinschen <corinna@vinschen.de>2019-08-16 17:36:06 +0300
committerCorinna Vinschen <corinna@vinschen.de>2019-08-18 15:02:01 +0300
commit7097b05eda2f8e9058eab4fda8dedacdfb7ffd7f (patch)
tree61529d1208c79386179fdd74491a709647ef1b0d /winsup/cygwin/sigproc.cc
parentb7399d5e6f8ad5b15cd725f66b3e49732393ef03 (diff)
Cygwin: select: revamp non-polling code for signalfd
Rather than waiting for signalfd_select_wait in a thread, which is racy, create a global event "my_pendingsigs_evt" which is set and reset by wait_sig depending only on the fact if blocked signals are pending or not. This in turn allows to WFMO on this event in select as soon as signalfds are present in the read descriptor set. Select's peek and verify will then check if one of the present signalfds is affected. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc17
1 files changed, 17 insertions, 0 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 8003e2db6..91abb717c 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -57,6 +57,9 @@ _cygtls NO_COPY *_sig_tls;
Static HANDLE my_sendsig;
Static HANDLE my_readsig;
+/* Used in select if a signalfd is part of the read descriptor set */
+HANDLE NO_COPY my_pendingsigs_evt;
+
/* Function declarations */
static int __reg1 checkstate (waitq *);
static __inline__ bool get_proc_lock (DWORD, DWORD);
@@ -455,6 +458,10 @@ sigproc_init ()
}
ProtectHandle (my_readsig);
myself->sendsig = my_sendsig;
+ my_pendingsigs_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (!my_pendingsigs_evt)
+ api_fatal ("couldn't create pending signal event, %E");
+
/* sync_proc_subproc is used by proc_subproc. It serializes
access to the children and proc arrays. */
sync_proc_subproc.init ("sync_proc_subproc");
@@ -1398,6 +1405,16 @@ wait_sig (VOID *)
qnext->si.si_signo = 0;
}
}
+ /* At least one signal still queued? The event is used in select
+ only, and only to decide if WFMO should wake up in case a
+ signalfd is waiting via select/poll for being ready to read a
+ pending signal. This method wakes up all threads hanging in
+ select and having a signalfd, as soon as a pending signal is
+ available, but it's certainly better than constant polling. */
+ if (sigq.start.next)
+ SetEvent (my_pendingsigs_evt);
+ else
+ ResetEvent (my_pendingsigs_evt);
if (pack.si.si_signo == SIGCHLD)
clearwait = true;
}