summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/sigproc.cc11
2 files changed, 15 insertions, 1 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 575c075ad..6a41485e1 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * sigproc.cc (exit_thread): Allow to exit the thread while running
+ global dtors. Explain why.
+
2013-06-02 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (CancelSynchronousIo): Define.
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index cf9053804..55c5bbac9 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -447,7 +447,16 @@ exit_thread (DWORD res)
# undef ExitThread
sigfillset (&_my_tls.sigmask); /* No signals wanted */
lock_process for_now; /* May block indefinitely when exiting. */
- if (exit_state)
+ /* ES_EXIT_STARTING indicates that exit is in progress. After setting
+ exit_state to ES_EXIT_STARTING, the global dtors are running first,
+ then the exit state is set to the next level in do_exit. We must not
+ block the thread exit while the global dtors are running, because
+ one of them might have called pthread_join, which is perfectly valid
+ for a global C++ destructor.
+ FIXME: Do we need another state between ES_EXIT_STARTING and
+ ES_SIGNAL_EXIT to narrow the gap in which the thread exit
+ is still valid? */
+ if (exit_state > ES_EXIT_STARTING)
{
for_now.release ();
Sleep (INFINITE);