From 168d7785fc2c13bca530c20b2015042903484b48 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 15 Mar 2004 02:47:35 +0000 Subject: [PATCH] * cygtls.cc (_cygtls::remove): Call remove_wq even when we can't necessarily get the cygtls table lock. * cygtls.h (_cygtls::remove_wq): Add wait argument. * sigproc.cc (_cygtls::remove_wq): Honor wait argument when acquiring lock. (proc_terminate): Don't NULL sync_proc_subproc since other threads may still try to access it. --- winsup/cygwin/ChangeLog | 10 ++++++++++ winsup/cygwin/cygtls.cc | 27 +++++++++++++++------------ winsup/cygwin/cygtls.h | 2 +- winsup/cygwin/sigproc.cc | 23 ++++++++++++----------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 712880ae3..2941cd3e0 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2004-03-14 Christopher Faylor + + * cygtls.cc (_cygtls::remove): Call remove_wq even when we can't + necessarily get the cygtls table lock. + * cygtls.h (_cygtls::remove_wq): Add wait argument. + * sigproc.cc (_cygtls::remove_wq): Honor wait argument when acquiring + lock. + (proc_terminate): Don't NULL sync_proc_subproc since other threads may + still try to access it. + 2004-03-12 Corinna Vinschen * errno.cc (errmap): Map ERROR_BEGINNING_OF_MEDIA and diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index f9770bbb0..f6f470634 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -150,19 +150,22 @@ void _cygtls::remove (DWORD wait) { debug_printf ("wait %p\n", wait); - sentry here (wait); - if (here.acquired ()) + do { - for (size_t i = 0; i < nthreads; i++) - if (this == cygheap->threadlist[i]) - { - if (i < --nthreads) - cygheap->threadlist[i] = cygheap->threadlist[nthreads]; - debug_printf ("removed %p element %d", this, i); - remove_wq (); - break; - } - } + sentry here (wait); + if (here.acquired ()) + { + for (size_t i = 0; i < nthreads; i++) + if (this == cygheap->threadlist[i]) + { + if (i < --nthreads) + cygheap->threadlist[i] = cygheap->threadlist[nthreads]; + debug_printf ("removed %p element %d", this, i); + break; + } + } + } while (0); + remove_wq (wait); } void diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index df4b62b65..997518654 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -154,7 +154,7 @@ struct _cygtls void set_threadkill () {threadkill = true;} void reset_threadkill () {threadkill = false;} int call_signal_handler () __attribute__ ((regparm (1))); - void remove_wq () __attribute__ ((regparm (1))); + void remove_wq (DWORD) __attribute__ ((regparm (1))); void fixup_after_fork () __attribute__ ((regparm (1))); void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 30318a7e1..c786153a6 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -471,17 +471,19 @@ out1: // FIXME: This is inelegant void -_cygtls::remove_wq () +_cygtls::remove_wq (DWORD wait) { - sync_proc_subproc->acquire (); - for (waitq *w = &waitq_head; w->next != NULL; w = w->next) - if (w->next == &wq) - { - ForceCloseHandle1 (wq.thread_ev, wq_ev); - w->next = wq.next; - break; - } - sync_proc_subproc->release (); + if (sync_proc_subproc && sync_proc_subproc->acquire (wait)) + { + for (waitq *w = &waitq_head; w->next != NULL; w = w->next) + if (w->next == &wq) + { + ForceCloseHandle1 (wq.thread_ev, wq_ev); + w->next = wq.next; + break; + } + sync_proc_subproc->release (); + } } /* Terminate the wait_subproc thread. @@ -536,7 +538,6 @@ proc_terminate (void) pchildren[i].release (); } nchildren = nzombies = 0; - sync_proc_subproc = NULL; } sigproc_printf ("leaving"); }