From 69154cfd6b621f9081c26ae523172197e47a8865 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 3 Jun 2013 09:48:54 +0000 Subject: [PATCH] * sigproc.cc (exit_thread): Allow to exit the thread while running global dtors. Explain why. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/sigproc.cc | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) 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 + + * sigproc.cc (exit_thread): Allow to exit the thread while running + global dtors. Explain why. + 2013-06-02 Corinna Vinschen * 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);