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:
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc98
1 files changed, 43 insertions, 55 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e585877b9..55c5bbac9 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -44,8 +44,6 @@ char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes
#define Static static NO_COPY
-Static HANDLE sig_hold; // Used to stop signal processing
-Static bool sigheld; // True if holding signals
Static int nprocs; // Number of deceased children
Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info
@@ -171,7 +169,7 @@ mychild (int pid)
/* Handle all subprocess requests
*/
int __reg2
-proc_subproc (DWORD what, DWORD val)
+proc_subproc (DWORD what, uintptr_t val)
{
int rc = 1;
int potential_match;
@@ -449,7 +447,16 @@ exit_thread (DWORD res)
# undef ExitThread
sigfillset (&_my_tls.sigmask); /* No signals wanted */
lock_process for_now; /* May block indefinitely when exiting. */
- if (exit_state)
+ /* ES_EXIT_STARTING indicates that exit is in progress. After setting
+ exit_state to ES_EXIT_STARTING, the global dtors are running first,
+ then the exit state is set to the next level in do_exit. We must not
+ block the thread exit while the global dtors are running, because
+ one of them might have called pthread_join, which is perfectly valid
+ for a global C++ destructor.
+ FIXME: Do we need another state between ES_EXIT_STARTING and
+ ES_SIGNAL_EXIT to narrow the gap in which the thread exit
+ is still valid? */
+ if (exit_state > ES_EXIT_STARTING)
{
for_now.release ();
Sleep (INFINITE);
@@ -478,24 +485,6 @@ exit_thread (DWORD res)
int __reg3
sig_send (_pinfo *p, int sig, _cygtls *tid)
{
- if (sig == __SIGHOLD)
- sigheld = true;
- else if (!sigheld)
- /* nothing */;
- else if (sig == __SIGFLUSH || sig == __SIGFLUSHFAST)
- return 0;
- else if (sig == __SIGNOHOLD)
- {
- SetEvent (sig_hold);
- sigheld = false;
- }
- else if (&_my_tls == _main_tls)
- {
-#ifdef DEBUGGING
- system_printf ("signal %d sent to %p while signals are on hold", sig, p);
-#endif
- return -1;
- }
siginfo_t si = {};
si.si_signo = sig;
si.si_code = SI_KERNEL;
@@ -991,7 +980,7 @@ child_info::sync (pid_t pid, HANDLE& hProcess, DWORD howlong)
hProcess = NULL;
}
}
- sigproc_printf ("pid %u, WFMO returned %d, exit_code %p, res %d", pid, x,
+ sigproc_printf ("pid %u, WFMO returned %d, exit_code %y, res %d", pid, x,
exit_code, res);
}
return res;
@@ -1002,7 +991,7 @@ child_info::proc_retry (HANDLE h)
{
if (!exit_code)
return EXITCODE_OK;
- sigproc_printf ("exit_code %p", exit_code);
+ sigproc_printf ("exit_code %y", exit_code);
switch (exit_code)
{
case STILL_ACTIVE: /* shouldn't happen */
@@ -1226,7 +1215,7 @@ static void WINAPI
wait_sig (VOID *)
{
_sig_tls = &_my_tls;
- sig_hold = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
+ bool sig_held = false;
sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p",
my_readsig, my_sendsig);
@@ -1275,33 +1264,7 @@ wait_sig (VOID *)
*pack.mask |= bit;
break;
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:
- {
- sigpacket *qnext;
- /* Check the queue for signals. There will always be at least one
- thing on the queue if this was a valid signal. */
- while ((qnext = q->next))
- {
- if (qnext->si.si_signo && qnext->process () <= 0)
- q = q->next;
- else
- {
- q->next = qnext->next;
- qnext->si.si_signo = 0;
- }
- }
- if (pack.si.si_signo == SIGCHLD)
- clearwait = true;
- }
+ sig_held = true;
break;
case __SIGSETPGRP:
init_console_handler (true);
@@ -1328,16 +1291,41 @@ wait_sig (VOID *)
}
}
break;
+ default:
+ if (pack.si.si_signo < 0)
+ sig_clear (-pack.si.si_signo);
+ else
+ sigq.add (pack);
+ case __SIGNOHOLD:
+ sig_held = false;
+ case __SIGFLUSH:
+ case __SIGFLUSHFAST:
+ if (!sig_held)
+ {
+ sigpacket *qnext;
+ /* Check the queue for signals. There will always be at least one
+ thing on the queue if this was a valid signal. */
+ while ((qnext = q->next))
+ {
+ if (qnext->si.si_signo && qnext->process () <= 0)
+ q = q->next;
+ else
+ {
+ q->next = qnext->next;
+ qnext->si.si_signo = 0;
+ }
+ }
+ if (pack.si.si_signo == SIGCHLD)
+ clearwait = true;
+ }
+ break;
}
if (clearwait && !have_execed)
proc_subproc (PROC_CLEARWAIT, 0);
- loop:
if (pack.wakeup)
{
sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
SetEvent (pack.wakeup);
}
- if (pack.si.si_signo == __SIGHOLD)
- WaitForSingleObject (sig_hold, INFINITE);
}
}