mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-22 16:49:45 +08:00
* cygtls.h (_cygtls::reset_signal_arrived): Actually reset the signal_arrived
event. (_cygtls::handle_SIGCONT): Declare ew function. * cygwait.cc (is_cw_sig_handle): Delete. (is_cw_sig_cont): New convenience define. (cygwait): Clear signal if is_cw_sig_cont and we got a SIGCONT. * cygwait.h (cw_wait_mask): Add cw_sig_cont. * exceptions.cc (sig_handle_tty_stop): Tighten "incyg" region. Use cw_sig_cont param for cygwait. Don't zero signal here outside of lock. (sigpacket::setup_handler): Don't check for in_forkee since we will now never get here in that state. (_cygtls::handle_SIGCONT): Define new function. (sigpacket::process): Call handle_SIGCONT early to deal with SIGCONT. Nuke continue_now handling. Allow SIGKILL to kill a suspended process. Delete a couple of now-unneeded labels. (_cygtls::call_signal_handler): Reorganize setting of incyg within lock. * sigproc.cc (pending_signals): Simplify. (pending_signals::clear): New method. (_cygtls::remove_wq): Reorganize to always close wq.thread_ev if it exists to avoid handle leaks. (sig_clear): Simplify by just calling sigq.clear(). (sig_dispatch_pending): Always call sigq.pending even in signal thread to force another loop in wait_sig. (sig_send): Remove a "goto out" just before out: label. (pending_signals::add): Simplify. (pending_signals::del): Delete. (pending_signals::next): Delete. (wait_sig): Define variable q to be the start of the signal queue. Just iterate through sigq queue, deleting processed or zeroed signals. Only set clearwait when the current signal is SIGCHLD. * sigproc.h: Add a comment about an unused enum.
This commit is contained in:
parent
037ad80a52
commit
9d2155089e
@ -1,3 +1,38 @@
|
|||||||
|
2013-04-08 Christopher Faylor <me.cygwin2013@cgf.cx>
|
||||||
|
|
||||||
|
* cygtls.h (_cygtls::reset_signal_arrived): Actually reset the
|
||||||
|
signal_arrived event.
|
||||||
|
(_cygtls::handle_SIGCONT): Declare ew function.
|
||||||
|
* cygwait.cc (is_cw_sig_handle): Delete.
|
||||||
|
(is_cw_sig_cont): New convenience define.
|
||||||
|
(cygwait): Clear signal if is_cw_sig_cont and we got a SIGCONT.
|
||||||
|
* cygwait.h (cw_wait_mask): Add cw_sig_cont.
|
||||||
|
* exceptions.cc (sig_handle_tty_stop): Tighten "incyg" region. Use
|
||||||
|
cw_sig_cont param for cygwait. Don't zero signal here outside of lock.
|
||||||
|
(sigpacket::setup_handler): Don't check for in_forkee since we will now
|
||||||
|
never get here in that state.
|
||||||
|
(_cygtls::handle_SIGCONT): Define new function.
|
||||||
|
(sigpacket::process): Call handle_SIGCONT early to deal with SIGCONT.
|
||||||
|
Nuke continue_now handling. Allow SIGKILL to kill a suspended process.
|
||||||
|
Delete a couple of now-unneeded labels.
|
||||||
|
(_cygtls::call_signal_handler): Reorganize setting of incyg within
|
||||||
|
lock.
|
||||||
|
* sigproc.cc (pending_signals): Simplify.
|
||||||
|
(pending_signals::clear): New method.
|
||||||
|
(_cygtls::remove_wq): Reorganize to always close wq.thread_ev if it
|
||||||
|
exists to avoid handle leaks.
|
||||||
|
(sig_clear): Simplify by just calling sigq.clear().
|
||||||
|
(sig_dispatch_pending): Always call sigq.pending even in signal thread
|
||||||
|
to force another loop in wait_sig.
|
||||||
|
(sig_send): Remove a "goto out" just before out: label.
|
||||||
|
(pending_signals::add): Simplify.
|
||||||
|
(pending_signals::del): Delete.
|
||||||
|
(pending_signals::next): Delete.
|
||||||
|
(wait_sig): Define variable q to be the start of the signal queue.
|
||||||
|
Just iterate through sigq queue, deleting processed or zeroed signals.
|
||||||
|
Only set clearwait when the current signal is SIGCHLD.
|
||||||
|
* sigproc.h: Add a comment about an unused enum.
|
||||||
|
|
||||||
2013-04-08 Corinna Vinschen <corinna@vinschen.de>
|
2013-04-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_socket.cc (get_inet_addr): Handle abstract AF_LOCAL socket.
|
* fhandler_socket.cc (get_inet_addr): Handle abstract AF_LOCAL socket.
|
||||||
|
@ -253,7 +253,13 @@ public:
|
|||||||
will_wait_for_signal = true;
|
will_wait_for_signal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void reset_signal_arrived () { will_wait_for_signal = false; }
|
void reset_signal_arrived ()
|
||||||
|
{
|
||||||
|
if (signal_arrived)
|
||||||
|
ResetEvent (signal_arrived);
|
||||||
|
will_wait_for_signal = false;
|
||||||
|
}
|
||||||
|
void handle_SIGCONT ();
|
||||||
private:
|
private:
|
||||||
void __reg3 call2 (DWORD (*) (void *, void *), void *, void *);
|
void __reg3 call2 (DWORD (*) (void *, void *), void *, void *);
|
||||||
/*gentls_offsets*/
|
/*gentls_offsets*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygwait.h
|
/* cygwait.h
|
||||||
|
|
||||||
Copyright 2011, 2012 Red Hat, Inc.
|
Copyright 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -17,9 +17,9 @@
|
|||||||
#define is_cw_cancel_self (mask & cw_cancel_self)
|
#define is_cw_cancel_self (mask & cw_cancel_self)
|
||||||
#define is_cw_sig (mask & cw_sig)
|
#define is_cw_sig (mask & cw_sig)
|
||||||
#define is_cw_sig_eintr (mask & cw_sig_eintr)
|
#define is_cw_sig_eintr (mask & cw_sig_eintr)
|
||||||
#define is_cw_sig_return (mask & cw_sig_return)
|
#define is_cw_sig_cont (mask & cw_sig_cont)
|
||||||
|
|
||||||
#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
|
#define is_cw_sig_handle (mask & (cw_sig | cw_sig_eintr | cw_sig_cont))
|
||||||
|
|
||||||
LARGE_INTEGER cw_nowait_storage;
|
LARGE_INTEGER cw_nowait_storage;
|
||||||
|
|
||||||
@ -83,10 +83,12 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
|
|||||||
{
|
{
|
||||||
_my_tls.lock ();
|
_my_tls.lock ();
|
||||||
int sig = _my_tls.sig;
|
int sig = _my_tls.sig;
|
||||||
|
if (is_cw_sig_cont && sig == SIGCONT)
|
||||||
|
_my_tls.sig = 0;
|
||||||
_my_tls.unlock ();
|
_my_tls.unlock ();
|
||||||
if (!sig)
|
if (!sig)
|
||||||
continue;
|
continue;
|
||||||
if (is_cw_sig_eintr)
|
if (is_cw_sig_eintr || (is_cw_sig_cont && sig == SIGCONT))
|
||||||
res = WAIT_SIGNALED; /* caller will deal with signals */
|
res = WAIT_SIGNALED; /* caller will deal with signals */
|
||||||
else if (_my_tls.call_signal_handler ())
|
else if (_my_tls.call_signal_handler ())
|
||||||
continue;
|
continue;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygwait.h
|
/* cygwait.h
|
||||||
|
|
||||||
Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
|
||||||
Red Hat, Inc.
|
Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
@ -19,7 +19,8 @@ enum cw_wait_mask
|
|||||||
cw_cancel = 0x0001,
|
cw_cancel = 0x0001,
|
||||||
cw_cancel_self = 0x0002,
|
cw_cancel_self = 0x0002,
|
||||||
cw_sig = 0x0004,
|
cw_sig = 0x0004,
|
||||||
cw_sig_eintr = 0x0008
|
cw_sig_eintr = 0x0008,
|
||||||
|
cw_sig_cont = 0x0010
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LARGE_INTEGER cw_nowait_storage;
|
extern LARGE_INTEGER cw_nowait_storage;
|
||||||
|
@ -686,23 +686,24 @@ extern "C" {
|
|||||||
static void
|
static void
|
||||||
sig_handle_tty_stop (int sig, siginfo_t *, void *)
|
sig_handle_tty_stop (int sig, siginfo_t *, void *)
|
||||||
{
|
{
|
||||||
_my_tls.incyg = 1;
|
|
||||||
/* Silently ignore attempts to suspend if there is no accommodating
|
/* Silently ignore attempts to suspend if there is no accommodating
|
||||||
cygwin parent to deal with this behavior. */
|
cygwin parent to deal with this behavior. */
|
||||||
if (!myself->cygstarted)
|
if (!myself->cygstarted)
|
||||||
myself->process_state &= ~PID_STOPPED;
|
myself->process_state &= ~PID_STOPPED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_my_tls.incyg = 1;
|
||||||
myself->stopsig = sig;
|
myself->stopsig = sig;
|
||||||
myself->alert_parent (sig);
|
myself->alert_parent (sig);
|
||||||
sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
|
sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
|
||||||
/* FIXME! This does nothing to suspend anything other than the main
|
/* FIXME! This does nothing to suspend anything other than the main
|
||||||
thread. */
|
thread. */
|
||||||
DWORD res = cygwait (NULL, cw_infinite, cw_sig_eintr);
|
/* Use special cygwait parameter to handle SIGCONT. _main_tls.sig will
|
||||||
|
be cleared under lock when SIGCONT is detected. */
|
||||||
|
DWORD res = cygwait (NULL, cw_infinite, cw_sig_cont);
|
||||||
switch (res)
|
switch (res)
|
||||||
{
|
{
|
||||||
case WAIT_SIGNALED:
|
case WAIT_SIGNALED:
|
||||||
_my_tls.sig = 0;
|
|
||||||
myself->stopsig = SIGCONT;
|
myself->stopsig = SIGCONT;
|
||||||
myself->alert_parent (SIGCONT);
|
myself->alert_parent (SIGCONT);
|
||||||
break;
|
break;
|
||||||
@ -710,8 +711,8 @@ sig_handle_tty_stop (int sig, siginfo_t *, void *)
|
|||||||
api_fatal ("WaitSingleObject returned %d", res);
|
api_fatal ("WaitSingleObject returned %d", res);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_my_tls.incyg = 0;
|
_my_tls.incyg = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} /* end extern "C" */
|
} /* end extern "C" */
|
||||||
|
|
||||||
@ -785,10 +786,6 @@ sigpacket::setup_handler (void *handler, struct sigaction& siga, _cygtls *tls)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (in_forkee)
|
|
||||||
yield (); /* Won't be able to send signals until we're finished
|
|
||||||
processing fork(). */
|
|
||||||
|
|
||||||
for (int n = 0; n < CALL_HANDLER_RETRY_OUTER; n++)
|
for (int n = 0; n < CALL_HANDLER_RETRY_OUTER; n++)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CALL_HANDLER_RETRY_INNER; i++)
|
for (int i = 0; i < CALL_HANDLER_RETRY_INNER; i++)
|
||||||
@ -1121,31 +1118,56 @@ signal_exit (int sig, siginfo_t *si)
|
|||||||
}
|
}
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
||||||
int __stdcall
|
/* Attempt to carefully handle SIGCONT when we are stopped. */
|
||||||
sigpacket::process ()
|
void
|
||||||
|
_cygtls::handle_SIGCONT ()
|
||||||
{
|
{
|
||||||
int rc = 1;
|
if (ISSTATE (myself, PID_STOPPED))
|
||||||
bool issig_wait = false;
|
|
||||||
bool continue_now = false;
|
|
||||||
struct sigaction& thissig = global_sigs[si.si_signo];
|
|
||||||
void *handler = have_execed ? NULL : (void *) thissig.sa_handler;
|
|
||||||
|
|
||||||
if (!cygwin_finished_initializing)
|
|
||||||
{
|
{
|
||||||
rc = -1;
|
|
||||||
goto really_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (si.si_signo == SIGCONT)
|
|
||||||
{
|
|
||||||
continue_now = ISSTATE (myself, PID_STOPPED);
|
|
||||||
myself->stopsig = 0;
|
myself->stopsig = 0;
|
||||||
myself->process_state &= ~PID_STOPPED;
|
myself->process_state &= ~PID_STOPPED;
|
||||||
|
int state = 0;
|
||||||
|
/* Carefully tell sig_handle_tty_stop to wake up. */
|
||||||
|
while (state < 2)
|
||||||
|
{
|
||||||
|
lock ();
|
||||||
|
if (sig)
|
||||||
|
yield (); /* state <= 1 */
|
||||||
|
else if (state)
|
||||||
|
state++; /* state == 2 */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sig = SIGCONT;
|
||||||
|
SetEvent (signal_arrived);
|
||||||
|
state++; /* state == 1 */
|
||||||
|
}
|
||||||
|
unlock ();
|
||||||
|
}
|
||||||
|
/* Tell wait_sig to handle any queued signals now that we're alive
|
||||||
|
again. */
|
||||||
|
sig_dispatch_pending (false);
|
||||||
|
}
|
||||||
/* Clear pending stop signals */
|
/* Clear pending stop signals */
|
||||||
sig_clear (SIGSTOP);
|
sig_clear (SIGSTOP);
|
||||||
sig_clear (SIGTSTP);
|
sig_clear (SIGTSTP);
|
||||||
sig_clear (SIGTTIN);
|
sig_clear (SIGTTIN);
|
||||||
sig_clear (SIGTTOU);
|
sig_clear (SIGTTOU);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
sigpacket::process ()
|
||||||
|
{
|
||||||
|
int rc = 1;
|
||||||
|
bool issig_wait = false;
|
||||||
|
struct sigaction& thissig = global_sigs[si.si_signo];
|
||||||
|
void *handler = have_execed ? NULL : (void *) thissig.sa_handler;
|
||||||
|
|
||||||
|
/* Don't try to send signals if we're just starting up since signal masks
|
||||||
|
may not be available. */
|
||||||
|
if (!cygwin_finished_initializing)
|
||||||
|
{
|
||||||
|
rc = -1;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigproc_printf ("signal %d processing", si.si_signo);
|
sigproc_printf ("signal %d processing", si.si_signo);
|
||||||
@ -1153,7 +1175,17 @@ sigpacket::process ()
|
|||||||
myself->rusage_self.ru_nsignals++;
|
myself->rusage_self.ru_nsignals++;
|
||||||
|
|
||||||
_cygtls *tls;
|
_cygtls *tls;
|
||||||
if (!sigtls)
|
if (si.si_signo == SIGCONT)
|
||||||
|
_main_tls->handle_SIGCONT ();
|
||||||
|
|
||||||
|
if (si.si_signo == SIGKILL)
|
||||||
|
tls = _main_tls; /* SIGKILL is special. It always goes through. */
|
||||||
|
else if (ISSTATE (myself, PID_STOPPED))
|
||||||
|
{
|
||||||
|
rc = -1; /* Don't send signals when stopped */
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (!sigtls)
|
||||||
{
|
{
|
||||||
tls = cygheap->find_tls (si.si_signo, issig_wait);
|
tls = cygheap->find_tls (si.si_signo, issig_wait);
|
||||||
sigproc_printf ("using tls %p", tls);
|
sigproc_printf ("using tls %p", tls);
|
||||||
@ -1169,7 +1201,8 @@ sigpacket::process ()
|
|||||||
tls = NULL;
|
tls = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tls || ISSTATE (myself, PID_STOPPED))
|
/* !tls means no threads available to catch a signal. */
|
||||||
|
if (!tls)
|
||||||
{
|
{
|
||||||
sigproc_printf ("signal %d blocked", si.si_signo);
|
sigproc_printf ("signal %d blocked", si.si_signo);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
@ -1225,6 +1258,7 @@ sigpacket::process ()
|
|||||||
goto dosig;
|
goto dosig;
|
||||||
|
|
||||||
stop:
|
stop:
|
||||||
|
tls = _main_tls;
|
||||||
handler = (void *) sig_handle_tty_stop;
|
handler = (void *) sig_handle_tty_stop;
|
||||||
thissig = global_sigs[SIGSTOP];
|
thissig = global_sigs[SIGSTOP];
|
||||||
goto dosig;
|
goto dosig;
|
||||||
@ -1232,17 +1266,8 @@ stop:
|
|||||||
exit_sig:
|
exit_sig:
|
||||||
handler = (void *) signal_exit;
|
handler = (void *) signal_exit;
|
||||||
thissig.sa_flags |= SA_SIGINFO;
|
thissig.sa_flags |= SA_SIGINFO;
|
||||||
if (si.si_signo == SIGKILL)
|
|
||||||
goto dispatch_sig;
|
|
||||||
|
|
||||||
dosig:
|
dosig:
|
||||||
if (ISSTATE (myself, PID_STOPPED) && !continue_now)
|
|
||||||
{
|
|
||||||
rc = -1; /* No signals delivered if stopped */
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_sig:
|
|
||||||
if (have_execed)
|
if (have_execed)
|
||||||
{
|
{
|
||||||
sigproc_printf ("terminating captive process");
|
sigproc_printf ("terminating captive process");
|
||||||
@ -1251,15 +1276,8 @@ dispatch_sig:
|
|||||||
/* Dispatch to the appropriate function. */
|
/* Dispatch to the appropriate function. */
|
||||||
sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
|
sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
|
||||||
rc = setup_handler (handler, thissig, tls);
|
rc = setup_handler (handler, thissig, tls);
|
||||||
continue_now = false;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (continue_now)
|
|
||||||
{
|
|
||||||
(tls ?: _main_tls)->sig = SIGCONT;
|
|
||||||
SetEvent (tls->signal_arrived);
|
|
||||||
}
|
|
||||||
really_done:
|
|
||||||
sigproc_printf ("returning %d", rc);
|
sigproc_printf ("returning %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -1293,11 +1311,11 @@ _cygtls::call_signal_handler ()
|
|||||||
|
|
||||||
sigset_t this_oldmask = set_process_mask_delta ();
|
sigset_t this_oldmask = set_process_mask_delta ();
|
||||||
int this_errno = saved_errno;
|
int this_errno = saved_errno;
|
||||||
sig = 0; /* Flag that we can accept another signal */
|
|
||||||
reset_signal_arrived ();
|
reset_signal_arrived ();
|
||||||
|
incyg = false;
|
||||||
|
sig = 0; /* Flag that we can accept another signal */
|
||||||
unlock (); /* unlock signal stack */
|
unlock (); /* unlock signal stack */
|
||||||
|
|
||||||
incyg = false;
|
|
||||||
/* no ucontext_t information provided yet, so third arg is NULL */
|
/* no ucontext_t information provided yet, so third arg is NULL */
|
||||||
thisfunc (thissig, &thissi, NULL);
|
thisfunc (thissig, &thissi, NULL);
|
||||||
incyg = true;
|
incyg = true;
|
||||||
|
@ -73,20 +73,15 @@ class pending_signals
|
|||||||
{
|
{
|
||||||
sigpacket sigs[NSIG + 1];
|
sigpacket sigs[NSIG + 1];
|
||||||
sigpacket start;
|
sigpacket start;
|
||||||
sigpacket *end;
|
|
||||||
sigpacket *prev;
|
|
||||||
sigpacket *curr;
|
|
||||||
bool retry;
|
bool retry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void reset () {curr = &start; prev = &start;}
|
|
||||||
void add (sigpacket&);
|
void add (sigpacket&);
|
||||||
void del ();
|
|
||||||
bool pending () {retry = true; return !!start.next;}
|
bool pending () {retry = true; return !!start.next;}
|
||||||
sigpacket *next ();
|
void clear (int sig) {sigs[sig].si.si_signo = 0;}
|
||||||
sigpacket *save () const {return curr;}
|
|
||||||
void restore (sigpacket *saved) {curr = saved;}
|
|
||||||
friend void __reg1 sig_dispatch_pending (bool);;
|
friend void __reg1 sig_dispatch_pending (bool);;
|
||||||
friend void WINAPI wait_sig (VOID *arg);
|
friend void WINAPI wait_sig (VOID *arg);
|
||||||
|
friend void sigproc_init ();
|
||||||
};
|
};
|
||||||
|
|
||||||
Static pending_signals sigq;
|
Static pending_signals sigq;
|
||||||
@ -338,18 +333,22 @@ out1:
|
|||||||
void
|
void
|
||||||
_cygtls::remove_wq (DWORD wait)
|
_cygtls::remove_wq (DWORD wait)
|
||||||
{
|
{
|
||||||
|
if (wq.thread_ev)
|
||||||
|
{
|
||||||
if (exit_state < ES_FINAL && waitq_head.next && sync_proc_subproc
|
if (exit_state < ES_FINAL && waitq_head.next && sync_proc_subproc
|
||||||
&& sync_proc_subproc.acquire (wait))
|
&& sync_proc_subproc.acquire (wait))
|
||||||
{
|
{
|
||||||
for (waitq *w = &waitq_head; w->next != NULL; w = w->next)
|
for (waitq *w = &waitq_head; w->next != NULL; w = w->next)
|
||||||
if (w->next == &wq)
|
if (w->next == &wq)
|
||||||
{
|
{
|
||||||
ForceCloseHandle1 (wq.thread_ev, wq_ev);
|
|
||||||
w->next = wq.next;
|
w->next = wq.next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sync_proc_subproc.release ();
|
sync_proc_subproc.release ();
|
||||||
}
|
}
|
||||||
|
ForceCloseHandle1 (wq.thread_ev, wq_ev);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the wait_subproc thread.
|
/* Terminate the wait_subproc thread.
|
||||||
@ -392,23 +391,9 @@ proc_terminate ()
|
|||||||
|
|
||||||
/* Clear pending signal */
|
/* Clear pending signal */
|
||||||
void __reg1
|
void __reg1
|
||||||
sig_clear (int target_sig)
|
sig_clear (int sig)
|
||||||
{
|
{
|
||||||
if (&_my_tls != _sig_tls)
|
sigq.clear (sig);
|
||||||
sig_send (myself, -target_sig);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sigpacket *q;
|
|
||||||
sigpacket *save = sigq.save ();
|
|
||||||
sigq.reset ();
|
|
||||||
while ((q = sigq.next ()))
|
|
||||||
if (q->si.si_signo == target_sig)
|
|
||||||
{
|
|
||||||
q->si.si_signo = __SIGDELETE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sigq.restore (save);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
@ -425,21 +410,10 @@ sigpending (sigset_t *mask)
|
|||||||
void __reg1
|
void __reg1
|
||||||
sig_dispatch_pending (bool fast)
|
sig_dispatch_pending (bool fast)
|
||||||
{
|
{
|
||||||
if (&_my_tls == _sig_tls)
|
|
||||||
{
|
|
||||||
#ifdef DEBUGGING
|
|
||||||
sigproc_printf ("exit_state %d, cur thread id %p, _sig_tls %p, sigq.start.next %p",
|
|
||||||
exit_state, GetCurrentThreadId (), _sig_tls, sigq.start.next);
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Non-atomically test for any signals pending and wake up wait_sig if any are
|
/* Non-atomically test for any signals pending and wake up wait_sig if any are
|
||||||
found. It's ok if there's a race here since the next call to this function
|
found. It's ok if there's a race here since the next call to this function
|
||||||
should catch it.
|
should catch it. */
|
||||||
FIXME: Eventually, wait_sig should wake up on its own to deal with pending
|
if (sigq.pending () && &_my_tls != _sig_tls)
|
||||||
signals. */
|
|
||||||
if (sigq.pending ())
|
|
||||||
sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
|
sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,7 +702,6 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
|||||||
|
|
||||||
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
||||||
_my_tls.call_signal_handler ();
|
_my_tls.call_signal_handler ();
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (communing && rc)
|
if (communing && rc)
|
||||||
@ -1232,48 +1205,21 @@ talktome (siginfo_t *si)
|
|||||||
new cygthread (commune_process, size, si, "commune");
|
new cygthread (commune_process, size, si, "commune");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a packet to the beginning of the queue.
|
||||||
|
Should only be called from signal thread. */
|
||||||
void
|
void
|
||||||
pending_signals::add (sigpacket& pack)
|
pending_signals::add (sigpacket& pack)
|
||||||
{
|
{
|
||||||
sigpacket *se;
|
sigpacket *se;
|
||||||
|
|
||||||
se = sigs + pack.si.si_signo;
|
se = sigs + pack.si.si_signo;
|
||||||
if (se->si.si_signo)
|
if (se->si.si_signo)
|
||||||
return;
|
return;
|
||||||
*se = pack;
|
*se = pack;
|
||||||
se->next = NULL;
|
se->next = NULL;
|
||||||
if (end)
|
|
||||||
end->next = se;
|
|
||||||
end = se;
|
|
||||||
if (!start.next)
|
|
||||||
start.next = se;
|
start.next = se;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
pending_signals::del ()
|
|
||||||
{
|
|
||||||
sigpacket *next = curr->next;
|
|
||||||
prev->next = next;
|
|
||||||
curr->si.si_signo = 0;
|
|
||||||
#ifdef DEBUGGING
|
|
||||||
curr->next = NULL;
|
|
||||||
#endif
|
|
||||||
if (end == curr)
|
|
||||||
end = prev;
|
|
||||||
curr = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigpacket *
|
|
||||||
pending_signals::next ()
|
|
||||||
{
|
|
||||||
sigpacket *res;
|
|
||||||
prev = curr;
|
|
||||||
if (!curr || !(curr = curr->next))
|
|
||||||
res = NULL;
|
|
||||||
else
|
|
||||||
res = curr;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process signals by waiting for signal data to arrive in a pipe.
|
/* Process signals by waiting for signal data to arrive in a pipe.
|
||||||
Set a completion event if one was specified. */
|
Set a completion event if one was specified. */
|
||||||
static void WINAPI
|
static void WINAPI
|
||||||
@ -1311,7 +1257,7 @@ wait_sig (VOID *)
|
|||||||
pack.mask = &dummy_mask;
|
pack.mask = &dummy_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigpacket *q;
|
sigpacket *q = &sigq.start;
|
||||||
bool clearwait = false;
|
bool clearwait = false;
|
||||||
switch (pack.si.si_signo)
|
switch (pack.si.si_signo)
|
||||||
{
|
{
|
||||||
@ -1324,8 +1270,7 @@ wait_sig (VOID *)
|
|||||||
case __SIGPENDING:
|
case __SIGPENDING:
|
||||||
*pack.mask = 0;
|
*pack.mask = 0;
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
sigq.reset ();
|
while ((q = q->next))
|
||||||
while ((q = sigq.next ()))
|
|
||||||
if (pack.sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
|
if (pack.sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
|
||||||
*pack.mask |= bit;
|
*pack.mask |= bit;
|
||||||
break;
|
break;
|
||||||
@ -1340,13 +1285,21 @@ wait_sig (VOID *)
|
|||||||
case __SIGNOHOLD:
|
case __SIGNOHOLD:
|
||||||
case __SIGFLUSH:
|
case __SIGFLUSH:
|
||||||
case __SIGFLUSHFAST:
|
case __SIGFLUSHFAST:
|
||||||
sigq.reset ();
|
|
||||||
while ((q = sigq.next ()))
|
|
||||||
{
|
{
|
||||||
int sig = q->si.si_signo;
|
sigpacket *qnext;
|
||||||
if (sig == __SIGDELETE || q->process () > 0)
|
/* Check the queue for signals. There will always be at least one
|
||||||
sigq.del ();
|
thing on the queue if this was a valid signal. */
|
||||||
if (sig == SIGCHLD)
|
while ((qnext = q->next))
|
||||||
|
{
|
||||||
|
if (qnext->si.si_signo && qnext->process () <= 0)
|
||||||
|
q = q->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q->next = qnext->next;
|
||||||
|
qnext->si.si_signo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pack.si.si_signo == SIGCHLD)
|
||||||
clearwait = true;
|
clearwait = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -20,7 +20,7 @@ enum
|
|||||||
__SIGSTRACE = -(NSIG + 2),
|
__SIGSTRACE = -(NSIG + 2),
|
||||||
__SIGCOMMUNE = -(NSIG + 3),
|
__SIGCOMMUNE = -(NSIG + 3),
|
||||||
__SIGPENDING = -(NSIG + 4),
|
__SIGPENDING = -(NSIG + 4),
|
||||||
__SIGDELETE = -(NSIG + 5),
|
__SIGDELETE = -(NSIG + 5), /* Not currently used */
|
||||||
__SIGFLUSHFAST = -(NSIG + 6),
|
__SIGFLUSHFAST = -(NSIG + 6),
|
||||||
__SIGHOLD = -(NSIG + 7),
|
__SIGHOLD = -(NSIG + 7),
|
||||||
__SIGNOHOLD = -(NSIG + 8),
|
__SIGNOHOLD = -(NSIG + 8),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user