From 67483cb2cdee37aa435fd108cea5310a873925a3 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 13 Sep 2005 17:08:54 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 43 +++++++++++++++++++++ winsup/cygwin/dcrt0.cc | 7 +--- winsup/cygwin/debug.cc | 2 - winsup/cygwin/devices.cc | 1 - winsup/cygwin/devices.in | 1 - winsup/cygwin/dtable.cc | 4 -- winsup/cygwin/environ.cc | 1 - winsup/cygwin/errno.cc | 1 - winsup/cygwin/exceptions.cc | 2 - winsup/cygwin/fhandler.cc | 4 -- winsup/cygwin/fhandler_console.cc | 2 - winsup/cygwin/pinfo.cc | 24 +++++++++--- winsup/cygwin/sigproc.cc | 62 ++++++++++++++++--------------- winsup/cygwin/sigproc.h | 3 +- 14 files changed, 97 insertions(+), 60 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d2c30c7ab..d83936a06 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,46 @@ +2005-09-13 Christopher Faylor + + * 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. + +2005-09-13 Christopher Faylor + + * 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. + 2005-09-13 Christopher Faylor * sigproc.cc (wait_sig): Be more defensive about detecting when we're diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 1783d5564..b7207667f 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -518,8 +518,6 @@ alloc_stack (child_info_fork *ci) ci->stacksize = 0; else alloc_stack_hard_way (ci, b + sizeof (b) - 1); - - return; } #ifdef DEBUGGING @@ -1059,10 +1057,7 @@ do_exit (int status) } if (exit_state < ES_SIGPROCTERMINATE) - { - exit_state = ES_SIGPROCTERMINATE; - sigproc_terminate (); - } + sigproc_terminate (); // sets exit_state directly myself->stopsig = 0; if (exit_state < ES_TITLE) diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index b7c2b59b4..be256b01b 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -153,8 +153,6 @@ add_handle (const char *func, int ln, HANDLE h, const char *name, bool inh) cygheap->debug.endh->next = hl; cygheap->debug.endh = hl; debug_printf ("protecting handle '%s', inherited flag %d", hl->name, hl->inherited); - - return; } static void __stdcall diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc index b35b3356c..0d469a85b 100644 --- a/winsup/cygwin/devices.cc +++ b/winsup/cygwin/devices.cc @@ -14899,7 +14899,6 @@ device::parse (_major_t major, _minor_t minor) if (!*this) devn = FHDEV (major, minor); - return; } void diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in index 326e5526e..63a677eb9 100644 --- a/winsup/cygwin/devices.in +++ b/winsup/cygwin/devices.in @@ -125,7 +125,6 @@ device::parse (_major_t major, _minor_t minor) if (!*this) devn = FHDEV (major, minor); - return; } void diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 220d28cc7..05d9037ab 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -788,8 +788,6 @@ dtable::vfork_parent_restore () cygheap->ctty->close (); // Undo previous bump of this archetype } cygheap->ctty_on_hold = NULL; - - return; } void @@ -824,8 +822,6 @@ dtable::vfork_child_fixup () cygheap->ctty_on_hold->close (); cygheap->ctty_on_hold = NULL; } - - return; } #endif /*NEWVFORK*/ diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 33c6c78fb..37d950ee0 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -666,7 +666,6 @@ parse_options (char *buf) } } debug_printf ("returning"); - return; } /* Set options from the registry. */ diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index a33a41945..e1f507948 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -306,7 +306,6 @@ seterrno_from_win_error (const char *file, int line, DWORD code) { syscall_printf ("%s:%d windows error %d", file, line, code); set_errno (geterrno_from_win_error (code, EACCES)); - return; } /* seterrno: Set `errno' based on GetLastError (). */ diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index f390669c0..939ec89ea 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -649,7 +649,6 @@ sig_handle_tty_stop (int sig) break; } _my_tls.incyg = 0; - return; } } @@ -1017,7 +1016,6 @@ set_signal_mask (sigset_t newmask, sigset_t& oldmask) else sigproc_printf ("not calling sig_dispatch_pending"); mask_sync.release (); - return; } int __stdcall diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 63ca99b4a..a8a27862a 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -789,7 +789,6 @@ fhandler_base::read (void *in_ptr, size_t& len) out: debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text"); - return; } int @@ -1398,7 +1397,6 @@ void fhandler_base::operator delete (void *p) { cfree (p); - return; } /* Normal I/O constructor */ @@ -1555,14 +1553,12 @@ void fhandler_base::seekdir (DIR *, _off64_t) { set_errno (ENOTDIR); - return; } void fhandler_base::rewinddir (DIR *) { set_errno (ENOTDIR); - return; } int diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 405dbb686..f1e180a95 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -546,7 +546,6 @@ err: sig_exit: set_sig_errno (EINTR); buflen = (size_t) -1; - return; } void @@ -1824,5 +1823,4 @@ fhandler_console::fixup_after_exec () CloseHandle (h); CloseHandle (oh); - return; } diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 0e89ca03b..9ce988db7 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -136,13 +136,12 @@ pinfo::zap_cwd () void pinfo::exit (DWORD n) { + sigproc_terminate (); exit_state = ES_FINAL; + cygthread::terminate (); if (n != EXITCODE_NOSET) - { - sigproc_terminate (); /* Just terminate signal and process stuff */ - self->exitcode = EXITCODE_SET | n;/* We're really exiting. Record the UNIX exit code. */ - } + self->exitcode = EXITCODE_SET | n;/* We're really exiting. Record the UNIX exit code. */ /* FIXME: There is a potential race between an execed process and its parent here. I hated to add a mutex just for this, though. */ @@ -161,12 +160,25 @@ pinfo::exit (DWORD n) int exitcode = self->exitcode & 0xffff; if (!self->cygstarted) exitcode >>= 8; - release (); _my_tls.stacklock = 0; _my_tls.stackptr = _my_tls.stack; - sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p", + if (&_my_tls == _main_tls) + { + sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p", + hProcess, n, exitcode); + ExitThread (exitcode); + } + else if (hMainThread) + { + sigproc_printf ("Calling TerminateThread since %p != %p, %p, n %p, exitcode %p", + &_my_tls, _main_tls, hProcess, n, exitcode); + TerminateThread (hMainThread, exitcode); + } + + sigproc_printf ("Calling ExitProcess since hMainthread is 0, hProcess %p, n %p, exitcode %p", hProcess, n, exitcode); + release (); ExitProcess (exitcode); } # undef self 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); } diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 74d8d3bfb..c135f32b3 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -22,7 +22,8 @@ enum __SIGDELETE = -(NSIG + 5), __SIGFLUSHFAST = -(NSIG + 6), __SIGHOLD = -(NSIG + 7), - __SIGNOHOLD = -(NSIG + 8) + __SIGNOHOLD = -(NSIG + 8), + __SIGEXIT = -(NSIG + 9) }; #endif