summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/sigproc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc128
1 files changed, 15 insertions, 113 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index eeeb4dc9b..b67b694ab 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1,7 +1,7 @@
/* sigproc.cc: inter/intra signal and sub process handler
- Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -31,7 +31,7 @@ details. */
#define WSSC 60000 // Wait for signal completion
#define WPSP 40000 // Wait for proc_subproc mutex
-#define no_signals_available(x) (!my_sendsig || ((x) && myself->exitcode & EXITCODE_SET) || (&_my_tls == _sig_tls))
+#define no_signals_available() (exit_state || (myself->exitcode & EXITCODE_SET) || (&_my_tls == _sig_tls))
/*
* Global variables
@@ -61,7 +61,6 @@ _cygtls NO_COPY *_sig_tls;
Static HANDLE my_sendsig;
Static HANDLE my_readsig;
-Static int signal_exit_code;
/* Function declarations */
static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1)));
@@ -354,53 +353,6 @@ _cygtls::remove_wq (DWORD wait)
}
}
-inline void
-close_my_readsig ()
-{
- HANDLE h;
- if ((h = InterlockedExchangePointer (&my_readsig, NULL)))
- ForceCloseHandle1 (h, my_readsig);
-}
-
-/* Exit due to a signal, even in presence of more exceptions. We used to just
- call exit, but a SIGSEGV shouldn't cause atexit routines to run.
- Should only be called from the signal thread. */
-void
-_cygtls::signal_exit (int rc)
-{
- signal_debugger (rc & 0x7f);
-
- if (rc == SIGQUIT || rc == SIGABRT)
- {
- CONTEXT c;
- c.ContextFlags = CONTEXT_FULL;
- GetThreadContext (hMainThread, &c);
- copy_context (&c);
- if (cygheap->rlim_core > 0UL)
- rc |= 0x80;
- }
-
- if (have_execed)
- {
- sigproc_printf ("terminating captive process");
- TerminateProcess (ch_spawn, sigExeced = rc);
- }
-
- if ((rc & 0x80) && !try_to_debug ())
- stackdump (thread_context.ebp, true);
-
- lock_process until_exit (true);
- if (have_execed || exit_state > ES_PROCESS_LOCKED)
- myself.exit (rc);
-
- /* Starve other threads in a vain attempt to stop them from doing something
- stupid. */
- SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
-
- sigproc_printf ("about to call do_exit (%x)", rc);
- do_exit (rc);
-}
-
/* Terminate the wait_subproc thread.
Called on process exit.
Also called by spawn_guts to disassociate any subprocesses from this
@@ -523,36 +475,11 @@ sigproc_terminate (exit_states es)
exit_states prior_exit_state = exit_state;
exit_state = es;
if (!cygwin_finished_initializing)
- sigproc_printf ("don't worry about signal thread");
+ /* nothing to do */;
else if (prior_exit_state >= ES_FINAL)
sigproc_printf ("already performed");
else
- {
- sigproc_printf ("entering");
- sig_send (myself_nowait, __SIGEXIT);
- proc_terminate (); // clean up process stuff
- }
-}
-
-/* Set up stuff so that the signal thread will know that we are
- exiting due to a signal. */
-void
-setup_signal_exit (int sig)
-{
- signal_exit_code = sig; /* Tell wait_sig() that we are exiting. */
- exit_state = ES_SIGNAL_EXIT; /* Tell the rest of the world that we are exiting. */
-
- if (&_my_tls != _sig_tls)
- {
- sigpacket sp = {};
- sp.si.si_signo = __SIGEXIT;
- DWORD len;
- /* Write a packet to the wait_sig thread. It will eventuall cause
- the process to exit too. So just wait for that to happen after
- sending the packet. */
- WriteFile (my_sendsig, &sp, sizeof (sp), &len, NULL);
- Sleep (INFINITE);
- }
+ proc_terminate (); // clean up process stuff
}
/* Exit the current thread very carefully.
@@ -576,7 +503,7 @@ exit_thread (DWORD res)
}
ProtectHandle1 (h, exit_thread);
siginfo_t si = {__SIGTHREADEXIT, SI_KERNEL};
- si.si_value.sival_ptr = h;
+ si.si_cyg = h;
lock_process for_now; /* May block indefinitely if we're exiting. */
if (exit_state)
{
@@ -599,7 +526,7 @@ sig_send (_pinfo *p, int sig, _cygtls *tid)
/* nothing */;
else if (sig == __SIGFLUSH || sig == __SIGFLUSHFAST)
return 0;
- else if (sig == __SIGNOHOLD || sig == __SIGEXIT)
+ else if (sig == __SIGNOHOLD)
{
SetEvent (sig_hold);
sigheld = false;
@@ -611,10 +538,9 @@ sig_send (_pinfo *p, int sig, _cygtls *tid)
#endif
return -1;
}
- siginfo_t si = {0};
+ siginfo_t si = {};
si.si_signo = sig;
si.si_code = SI_KERNEL;
- si.si_pid = si.si_uid = si.si_errno = 0;
return sig_send (p, si, tid);
}
@@ -648,7 +574,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
- if (no_signals_available (si.si_signo != __SIGEXIT))
+ if (no_signals_available ())
{
set_errno (EAGAIN);
goto out; // Either exiting or not yet initializing
@@ -778,7 +704,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
- if (no_signals_available (true))
+ if (no_signals_available ())
sigproc_printf ("I'm going away now");
else if (!p->exec_sendsig)
system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
@@ -818,7 +744,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
rc = 0; // Successful exit
else
{
- if (!no_signals_available (true))
+ if (!no_signals_available ())
system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E",
si.si_signo, rc);
set_errno (ENOSYS);
@@ -1390,12 +1316,6 @@ wait_sig (VOID *)
WaitForSingleObject (sig_hold, INFINITE);
DWORD nb;
- /* If signal_exit_code is set then we are shutting down due to a signal.
- We'll exit this loop iff there is nothing more in the signal queue. */
- if (signal_exit_code
- && (!PeekNamedPipe (my_readsig, NULL, 0, NULL, &nb, NULL) || !nb))
- break;
-
pack.sigtls = NULL;
if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL))
break;
@@ -1415,8 +1335,9 @@ wait_sig (VOID *)
continue;
}
- if (signal_exit_code && pack.si.si_signo > 0)
- continue; /* No more real signals allowed */
+ /* Don't process signals when we start exiting */
+ if (exit_state && pack.si.si_signo)
+ continue;
sigset_t dummy_mask;
if (!pack.mask)
@@ -1459,10 +1380,6 @@ wait_sig (VOID *)
clearwait = true;
}
break;
- case __SIGEXIT:
- my_sendsig = NULL;
- sigproc_printf ("saw __SIGEXIT");
- break; /* handle below */
case __SIGSETPGRP:
init_console_handler (true);
break;
@@ -1475,7 +1392,7 @@ wait_sig (VOID *)
release the process lock which it held and close it's handle.
See cgf-000017 in DevNotes for more details.
*/
- HANDLE h = (HANDLE) pack.si.si_value.sival_ptr;
+ HANDLE h = (HANDLE) pack.si.si_cyg;
DWORD res = WaitForSingleObject (h, 5000);
lock_process::force_release (pack.sigtls);
ForceCloseHandle1 (h, exit_thread);
@@ -1519,20 +1436,5 @@ wait_sig (VOID *)
sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
SetEvent (pack.wakeup);
}
- if (pack.si.si_signo == __SIGEXIT)
- break;
}
-
- sigproc_printf ("signal thread exiting");
-
- my_sendsig = NULL; /* Make no_signals_allowed return true */
- close_my_readsig (); /* Cause any sig_send's to stop */
-
- if (signal_exit_code)
- _my_tls.signal_exit (signal_exit_code);
-
- /* Just wait for the process to go away. Otherwise, this thread's
- exit value could be interpreted as the process exit value.
- See cgf-000017 in DevNotes for more details. */
- Sleep (INFINITE);
}