From d01efdbe6ef73e31eca061c031bab84c614a3fe4 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 16 Aug 2012 17:11:41 +0000 Subject: [PATCH] * cygheap.cc (init_cygheap::find_tls): Don't consider unitialized threads. * cygtls.cc (_cygtls::operator HANDLE): Return NULL when tid is not set. * exceptions.cc (setup_handler): Don't try to suspend a thread if it has no handle. --- winsup/cygwin/ChangeLog | 9 +++++++ winsup/cygwin/cygheap.cc | 6 +++-- winsup/cygwin/cygtls.h | 2 +- winsup/cygwin/exceptions.cc | 48 ++++++++++++++++++++----------------- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7a76bcc83..44d21176f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2012-08-16 Christopher Faylor + + * cygheap.cc (init_cygheap::find_tls): Don't consider unitialized + threads. + * cygtls.cc (_cygtls::operator HANDLE): Return NULL when tid is not + set. + * exceptions.cc (setup_handler): Don't try to suspend a thread if it + has no handle. + 2012-08-15 Christopher Faylor Rename cancelable_wait -> cygwait throughout. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 639f4e662..6c37cb510 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -628,14 +628,16 @@ init_cygheap::find_tls (int sig) { threadlist_ix = -1; while (++threadlist_ix < (int) nthreads) - if (sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) + if (threadlist[threadlist_ix]->tid + && sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) { t = cygheap->threadlist[threadlist_ix]; goto out; } threadlist_ix = -1; while (++threadlist_ix < (int) nthreads) - if (!sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) + if (threadlist[threadlist_ix]->tid + && !sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) { t = cygheap->threadlist[threadlist_ix]; break; diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 134fde290..98b63aeb1 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -226,7 +226,7 @@ public: void signal_debugger (int) __attribute__ ((regparm(2))); #ifdef CYGTLS_HANDLE - operator HANDLE () const {return tid->win32_obj_id;} + operator HANDLE () const {return tid ? NULL : tid->win32_obj_id;} #endif void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3))); int call_signal_handler () __attribute__ ((regparm (1))); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 15ef965ac..35b119e9f 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -846,30 +846,34 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) DWORD res; HANDLE hth = (HANDLE) *tls; - - /* Suspend the thread which will receive the signal. - If one of these conditions is not true we loop. - If the thread is already suspended (which can occur when a program - has called SuspendThread on itself) then just queue the signal. */ - - sigproc_printf ("suspending thread, tls %p, _main_tls %p", tls, _main_tls); - res = SuspendThread (hth); - /* Just set pending if thread is already suspended */ - if (res) - { - ResumeThread (hth); - goto out; - } - cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - if (!GetThreadContext (hth, &cx)) - sigproc_printf ("couldn't get context of thread, %E"); + if (!hth) + sigproc_printf ("thread handle NULL, not set up yet?"); else - interrupted = tls->interrupt_now (&cx, sig, handler, siga); + { + /* Suspend the thread which will receive the signal. + If one of these conditions is not true we loop. + If the thread is already suspended (which can occur when a program + has called SuspendThread on itself) then just queue the signal. */ - tls->unlock (); - ResumeThread (hth); - if (interrupted) - goto out; + sigproc_printf ("suspending thread, tls %p, _main_tls %p", tls, _main_tls); + res = SuspendThread (hth); + /* Just set pending if thread is already suspended */ + if (res) + { + ResumeThread (hth); + goto out; + } + cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + if (!GetThreadContext (hth, &cx)) + sigproc_printf ("couldn't get context of thread, %E"); + else + interrupted = tls->interrupt_now (&cx, sig, handler, siga); + + tls->unlock (); + ResumeThread (hth); + if (interrupted) + goto out; + } sigproc_printf ("couldn't interrupt. trying again."); yield ();