* 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>
* 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;
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)

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

View File

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

View File

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

View File

@ -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*/

View File

@ -666,7 +666,6 @@ parse_options (char *buf)
}
}
debug_printf ("returning");
return;
}
/* 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);
set_errno (geterrno_from_win_error (code, EACCES));
return;
}
/* seterrno: Set `errno' based on GetLastError (). */

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

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

View File

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