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.cc62
1 files changed, 33 insertions, 29 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 143e0a62d..5427d4632 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -38,7 +38,7 @@ details. */
#define WSSC 60000 // Wait for signal completion
#define WPSP 40000 // Wait for proc_subproc mutex
-#define no_signals_available() (!hwait_sig || (myself->sendsig == INVALID_HANDLE_VALUE) || exit_state)
+#define no_signals_available() (!hwait_sig || (myself->exitcode & EXITCODE_SET) && !my_sendsig)
#define NPROCS 256
@@ -80,6 +80,7 @@ static __inline__ bool get_proc_lock (DWORD, DWORD);
static bool __stdcall remove_proc (int);
static bool __stdcall stopped_or_terminated (waitq *, _pinfo *);
static DWORD WINAPI wait_sig (VOID *arg);
+static HANDLE NO_COPY my_sendsig;
/* wait_sig bookkeeping */
@@ -166,7 +167,7 @@ get_proc_lock (DWORD what, DWORD val)
static bool __stdcall
proc_can_be_signalled (_pinfo *p)
{
- if (p->sendsig != INVALID_HANDLE_VALUE)
+ if (!(p->exitcode & EXITCODE_SET))
{
if (p == myself_nowait || p == myself)
if (hwait_sig)
@@ -428,7 +429,6 @@ sig_clear (int target_sig)
}
sigq.restore (save);
}
- return;
}
extern "C" int
@@ -493,7 +493,6 @@ sigproc_init ()
global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
sigproc_printf ("process/signal handling enabled(%x)", myself->process_state);
- return;
}
/* Called on process termination to terminate signal and process threads.
@@ -501,23 +500,15 @@ sigproc_init ()
void __stdcall
sigproc_terminate (void)
{
- hwait_sig = NULL;
-
- if (myself->sendsig == INVALID_HANDLE_VALUE)
- sigproc_printf ("sigproc handling not active");
+ if (exit_state > ES_SIGPROCTERMINATE)
+ sigproc_printf ("already performed");
else
{
+ exit_state = ES_SIGPROCTERMINATE;
sigproc_printf ("entering");
- if (!hExeced)
- {
- HANDLE sendsig = myself->sendsig;
- myself->sendsig = INVALID_HANDLE_VALUE;
- CloseHandle (sendsig);
- }
+ sig_send (myself_nowait, __SIGEXIT);
+ proc_terminate (); // clean up process stuff
}
- proc_terminate (); // clean up process stuff
-
- return;
}
int __stdcall
@@ -545,7 +536,18 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
pack.wakeup = NULL;
bool wait_for_completion;
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
- wait_for_completion = false;
+ {
+ /* It is possible that the process is not yet ready to receive messages
+ * or that it has exited. Detect this.
+ */
+ if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
+ {
+ sigproc_printf ("invalid pid %d(%x), signal %d",
+ p->pid, p->process_state, si.si_signo);
+ goto out;
+ }
+ wait_for_completion = false;
+ }
else
{
if (no_signals_available ())
@@ -561,18 +563,9 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
p = myself;
}
- /* It is possible that the process is not yet ready to receive messages
- * or that it has exited. Detect this.
- */
- if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
- {
- sigproc_printf ("invalid pid %d(%x), signal %d",
- p->pid, p->process_state, si.si_signo);
- goto out;
- }
if (its_me)
- sendsig = myself->sendsig;
+ sendsig = my_sendsig;
else
{
HANDLE dupsig;
@@ -1005,6 +998,7 @@ wait_sig (VOID *self)
if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), 0))
api_fatal ("couldn't create signal pipe, %E");
sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
+ my_sendsig = myself->sendsig;
/* Setting dwProcessId flags that this process is now capable of receiving
signals. Prior to this, dwProcessId was set to the windows pid of
@@ -1028,7 +1022,7 @@ wait_sig (VOID *self)
sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break;
- if (exit_state || myself->sendsig == INVALID_HANDLE_VALUE)
+ if (exit_state || pack.si.si_signo == __SIGEXIT)
break;
if (nb != sizeof (pack))
@@ -1128,6 +1122,16 @@ wait_sig (VOID *self)
}
}
+ my_sendsig = NULL;
sigproc_printf ("done");
+ if (WaitForSingleObject (hMainThread, 5000) == WAIT_OBJECT_0)
+ {
+ DWORD exitcode = 1;
+ myself.release ();
+ GetExitCodeThread (hMainThread, &exitcode);
+ sigproc_printf ("Calling ExitProcess, exitcode %p",
+ exitcode);
+ ExitProcess (exitcode);
+ }
ExitThread (0);
}