* 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

@ -1,3 +1,46 @@
2005-09-13 Christopher Faylor <cgf@timesys.com>
* 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 <cgf@timesys.com>
* 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 <cgf@timesys.com> 2005-09-13 Christopher Faylor <cgf@timesys.com>
* sigproc.cc (wait_sig): Be more defensive about detecting when we're * sigproc.cc (wait_sig): Be more defensive about detecting when we're

View File

@ -518,8 +518,6 @@ alloc_stack (child_info_fork *ci)
ci->stacksize = 0; ci->stacksize = 0;
else else
alloc_stack_hard_way (ci, b + sizeof (b) - 1); alloc_stack_hard_way (ci, b + sizeof (b) - 1);
return;
} }
#ifdef DEBUGGING #ifdef DEBUGGING
@ -1059,10 +1057,7 @@ do_exit (int status)
} }
if (exit_state < ES_SIGPROCTERMINATE) if (exit_state < ES_SIGPROCTERMINATE)
{ sigproc_terminate (); // sets exit_state directly
exit_state = ES_SIGPROCTERMINATE;
sigproc_terminate ();
}
myself->stopsig = 0; myself->stopsig = 0;
if (exit_state < ES_TITLE) if (exit_state < ES_TITLE)

View File

@ -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->next = hl;
cygheap->debug.endh = hl; cygheap->debug.endh = hl;
debug_printf ("protecting handle '%s', inherited flag %d", hl->name, hl->inherited); debug_printf ("protecting handle '%s', inherited flag %d", hl->name, hl->inherited);
return;
} }
static void __stdcall static void __stdcall

View File

@ -14899,7 +14899,6 @@ device::parse (_major_t major, _minor_t minor)
if (!*this) if (!*this)
devn = FHDEV (major, minor); devn = FHDEV (major, minor);
return;
} }
void void

View File

@ -125,7 +125,6 @@ device::parse (_major_t major, _minor_t minor)
if (!*this) if (!*this)
devn = FHDEV (major, minor); devn = FHDEV (major, minor);
return;
} }
void void

View File

@ -788,8 +788,6 @@ dtable::vfork_parent_restore ()
cygheap->ctty->close (); // Undo previous bump of this archetype cygheap->ctty->close (); // Undo previous bump of this archetype
} }
cygheap->ctty_on_hold = NULL; cygheap->ctty_on_hold = NULL;
return;
} }
void void
@ -824,8 +822,6 @@ dtable::vfork_child_fixup ()
cygheap->ctty_on_hold->close (); cygheap->ctty_on_hold->close ();
cygheap->ctty_on_hold = NULL; cygheap->ctty_on_hold = NULL;
} }
return;
} }
#endif /*NEWVFORK*/ #endif /*NEWVFORK*/

View File

@ -666,7 +666,6 @@ parse_options (char *buf)
} }
} }
debug_printf ("returning"); debug_printf ("returning");
return;
} }
/* Set options from the registry. */ /* Set options from the registry. */

View File

@ -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); syscall_printf ("%s:%d windows error %d", file, line, code);
set_errno (geterrno_from_win_error (code, EACCES)); set_errno (geterrno_from_win_error (code, EACCES));
return;
} }
/* seterrno: Set `errno' based on GetLastError (). */ /* seterrno: Set `errno' based on GetLastError (). */

View File

@ -649,7 +649,6 @@ sig_handle_tty_stop (int sig)
break; break;
} }
_my_tls.incyg = 0; _my_tls.incyg = 0;
return;
} }
} }
@ -1017,7 +1016,6 @@ set_signal_mask (sigset_t newmask, sigset_t& oldmask)
else else
sigproc_printf ("not calling sig_dispatch_pending"); sigproc_printf ("not calling sig_dispatch_pending");
mask_sync.release (); mask_sync.release ();
return;
} }
int __stdcall int __stdcall

View File

@ -789,7 +789,6 @@ fhandler_base::read (void *in_ptr, size_t& len)
out: out:
debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text"); debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
return;
} }
int int
@ -1398,7 +1397,6 @@ void
fhandler_base::operator delete (void *p) fhandler_base::operator delete (void *p)
{ {
cfree (p); cfree (p);
return;
} }
/* Normal I/O constructor */ /* Normal I/O constructor */
@ -1555,14 +1553,12 @@ void
fhandler_base::seekdir (DIR *, _off64_t) fhandler_base::seekdir (DIR *, _off64_t)
{ {
set_errno (ENOTDIR); set_errno (ENOTDIR);
return;
} }
void void
fhandler_base::rewinddir (DIR *) fhandler_base::rewinddir (DIR *)
{ {
set_errno (ENOTDIR); set_errno (ENOTDIR);
return;
} }
int int

View File

@ -546,7 +546,6 @@ err:
sig_exit: sig_exit:
set_sig_errno (EINTR); set_sig_errno (EINTR);
buflen = (size_t) -1; buflen = (size_t) -1;
return;
} }
void void
@ -1824,5 +1823,4 @@ fhandler_console::fixup_after_exec ()
CloseHandle (h); CloseHandle (h);
CloseHandle (oh); CloseHandle (oh);
return;
} }

View File

@ -136,13 +136,12 @@ pinfo::zap_cwd ()
void void
pinfo::exit (DWORD n) pinfo::exit (DWORD n)
{ {
sigproc_terminate ();
exit_state = ES_FINAL; exit_state = ES_FINAL;
cygthread::terminate (); cygthread::terminate ();
if (n != EXITCODE_NOSET) 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 /* FIXME: There is a potential race between an execed process and its
parent here. I hated to add a mutex just for this, though. */ 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; int exitcode = self->exitcode & 0xffff;
if (!self->cygstarted) if (!self->cygstarted)
exitcode >>= 8; exitcode >>= 8;
release ();
_my_tls.stacklock = 0; _my_tls.stacklock = 0;
_my_tls.stackptr = _my_tls.stack; _my_tls.stackptr = _my_tls.stack;
if (&_my_tls == _main_tls)
{
sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p", sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode); 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); ExitProcess (exitcode);
} }
# undef self # undef self

View File

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

View File

@ -22,7 +22,8 @@ enum
__SIGDELETE = -(NSIG + 5), __SIGDELETE = -(NSIG + 5),
__SIGFLUSHFAST = -(NSIG + 6), __SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7), __SIGHOLD = -(NSIG + 7),
__SIGNOHOLD = -(NSIG + 8) __SIGNOHOLD = -(NSIG + 8),
__SIGEXIT = -(NSIG + 9)
}; };
#endif #endif