summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/exceptions.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-11-28 20:46:13 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-11-28 20:46:13 +0000
commit26158dc3e9c20fc0488944f0c3eefdc19255e7da (patch)
tree93f7cb9eab294721a54e3892e5e81be7791c0544 /winsup/cygwin/exceptions.cc
parentc2f50c4099b5b3db7dca5797bde8c5886d999c36 (diff)
downloadcygnal-26158dc3e9c20fc0488944f0c3eefdc19255e7da.tar.gz
cygnal-26158dc3e9c20fc0488944f0c3eefdc19255e7da.tar.bz2
cygnal-26158dc3e9c20fc0488944f0c3eefdc19255e7da.zip
* cygheap.cc (init_cygheap::init_tls_list): Accommodate threadlist
having a new type threadlist_t *. Convert commented out code into an #if 0. Create thread mutex. Explain why. (init_cygheap::remove_tls): Drop timeout value. Always wait infinitely for tls_sentry. Return mutex HANDLE of just deleted threadlist entry. (init_cygheap::find_tls): New implementation taking tls pointer as search parameter. Return threadlist_t *. (init_cygheap::find_tls): Return threadlist_t *. Define ix as auto variable. Drop exception handling since crash must be made impossible due to correct synchronization. Return with locked mutex. * cygheap.h (struct threadlist_t): Define. (struct init_cygheap): Convert threadlist to threadlist_t type. (init_cygheap::remove_tls): Align declaration to above change. (init_cygheap::find_tls): Ditto. (init_cygheap::unlock_tls): Define. * cygtls.cc (_cygtls::remove): Unlock and close mutex when finishing. * exceptions.cc (sigpacket::process): Lock _cygtls area of thread before accessing it. * fhandler_termios.cc (fhandler_termios::bg_check): Ditto. * sigproc.cc (sig_send): Ditto. * thread.cc (pthread::exit): Ditto. Add comment. (pthread::cancel): Ditto.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc62
1 files changed, 46 insertions, 16 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 4e9c77036..c16b073c6 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1299,6 +1299,9 @@ sigpacket::process ()
struct sigaction& thissig = global_sigs[si.si_signo];
void *handler = have_execed ? NULL : (void *) thissig.sa_handler;
+ threadlist_t *tl_entry = NULL;
+ _cygtls *tls = NULL;
+
/* Don't try to send signals if we're just starting up since signal masks
may not be available. */
if (!cygwin_finished_initializing)
@@ -1311,12 +1314,19 @@ sigpacket::process ()
myself->rusage_self.ru_nsignals++;
- _cygtls *tls;
if (si.si_signo == SIGCONT)
- _main_tls->handle_SIGCONT ();
+ {
+ tl_entry = cygheap->find_tls (_main_tls);
+ _main_tls->handle_SIGCONT ();
+ cygheap->unlock_tls (tl_entry);
+ }
+ /* SIGKILL is special. It always goes through. */
if (si.si_signo == SIGKILL)
- tls = _main_tls; /* SIGKILL is special. It always goes through. */
+ {
+ tl_entry = cygheap->find_tls (_main_tls);
+ tls = _main_tls;
+ }
else if (ISSTATE (myself, PID_STOPPED))
{
rc = -1; /* Don't send signals when stopped */
@@ -1324,18 +1334,29 @@ sigpacket::process ()
}
else if (!sigtls)
{
- tls = cygheap->find_tls (si.si_signo, issig_wait);
- sigproc_printf ("using tls %p", tls);
+ tl_entry = cygheap->find_tls (si.si_signo, issig_wait);
+ if (tl_entry)
+ {
+ tls = tl_entry->thread;
+ sigproc_printf ("using tls %p", tls);
+ }
}
else
{
- tls = sigtls;
- if (sigismember (&tls->sigwait_mask, si.si_signo))
- issig_wait = true;
- else if (!sigismember (&tls->sigmask, si.si_signo))
- issig_wait = false;
- else
- tls = NULL;
+ tl_entry = cygheap->find_tls (sigtls);
+ if (tl_entry)
+ {
+ tls = tl_entry->thread;
+ if (sigismember (&tls->sigwait_mask, si.si_signo))
+ issig_wait = true;
+ else if (!sigismember (&tls->sigmask, si.si_signo))
+ issig_wait = false;
+ else
+ {
+ cygheap->unlock_tls (tl_entry);
+ tls = NULL;
+ }
+ }
}
/* !tls means no threads available to catch a signal. */
@@ -1371,19 +1392,22 @@ sigpacket::process ()
}
/* Clear pending SIGCONT on stop signals */
- if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
+ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN
+ || si.si_signo == SIGTTOU)
sig_clear (SIGCONT);
if (handler == (void *) SIG_DFL)
{
- if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
+ if (si.si_signo == SIGCHLD || si.si_signo == SIGIO
+ || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
|| si.si_signo == SIGURG)
{
sigproc_printf ("signal %d default is currently ignore", si.si_signo);
goto done;
}
- if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
+ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN
+ || si.si_signo == SIGTTOU)
goto stop;
goto exit_sig;
@@ -1395,7 +1419,12 @@ sigpacket::process ()
goto dosig;
stop:
- tls = _main_tls;
+ if (tls != _main_tls)
+ {
+ cygheap->unlock_tls (tl_entry);
+ tl_entry = cygheap->find_tls (_main_tls);
+ tls = _main_tls;
+ }
handler = (void *) sig_handle_tty_stop;
thissig = global_sigs[SIGSTOP];
goto dosig;
@@ -1415,6 +1444,7 @@ dosig:
rc = setup_handler (handler, thissig, tls);
done:
+ cygheap->unlock_tls (tl_entry);
sigproc_printf ("returning %d", rc);
return rc;