* dcrt0.cc (do_exit): Rely on sigproc_terminate to set exit_state

appropriately.
* pinfo.cc (pinfo::exit): Always call sigproc_terminate here.  Rely on
sigproc_terminate to signal signal thread to handle eventual process exit.
* sigproc.cc (no_signals_available): Change criteria for determining if this
process can handle signals to itself.
(my_sendsig): New variable.  Copy of my sendsig handle.
(proc_can_be_signalled): Don't send signals if exit code is set.
(sigproc_terminate): Use and set exit_state appropriately to determine when to
do anything.  Send __SIGEXIT to self to control process exit.
(sig_send): Use my_sendsig for sending signals.  Don't call
proc_can_be_signalled for myself since the criteria is now different for
sending signals to myself.
(wait_sig): Copy myself->sendsig to my_sendsig for future use.  Exit signal
loop when __SIGEXIT is received.  Wait for main thread to exit and use its exit
status to actually exit process.
* sigproc.h (__SIGEXIT): New enum.
* dcrt0.cc (alloc_stack): Eliminate superfluous "return;".
* debug.cc (add_handle): Ditto.
* devices.in (device::parse): Ditto.
* dtable.cc (dtable::vfork_parent_restore): Ditto.
(dtable::vfork_child_fixup): Ditto.
* environ.cc (parse_options): Ditto.
* errno.cc (seterrno_from_win_error): Ditto.
* exceptions.cc (sig_handle_tty_stop): Ditto.
(set_signal_mask): Ditto.
* fhandler.cc (fhandler_base::read): Ditto.
(fhandler_base::operator delete): Ditto.
(fhandler_base::seekdir): Ditto.
(fhandler_base::rewinddir): Ditto.
* fhandler_console.cc (fhandler_console::read): Ditto.
(fhandler_console::fixup_after_exec): Ditto.
* sigproc.cc (sigproc_init): Ditto.
(sigproc_terminate): Ditto.

* devices.cc: Regenerate.
This commit is contained in:
Christopher Faylor
2005-09-13 17:08:54 +00:00
parent 00fb79f70e
commit 67483cb2cd
14 changed files with 97 additions and 60 deletions

View File

@@ -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);
}