diff --git a/interface/wx/thread.h b/interface/wx/thread.h index fd1149d1fb..b63c35084d 100644 --- a/interface/wx/thread.h +++ b/interface/wx/thread.h @@ -486,8 +486,10 @@ public: will be executed in the context of the thread that called Delete() and not in this thread's context. - TestDestroy() will be true for the thread before OnDelete() gets - executed. + Note that TestDestroy() will block until OnDelete() returns, so this + function should return as quickly as possible and definitely shouldn't + perform any GUI actions nor try acquiring any locks, as this could + easily result in a deadlock. @since 2.9.2 diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index f8cca7dd17..4cd5863db4 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -1575,10 +1575,16 @@ wxThreadError wxThread::Delete(ExitCode *rc, wxThreadWait WXUNUSED(waitMode)) // ask the thread to stop m_internal->SetCancelFlag(); - m_critsect.Leave(); - + // Normally we should never call out while holding the lock (on m_critsect + // in this case), but we can't do it later because as soon as we unlock it, + // this object may be destroyed as the thread executing its Entry() may + // call TestDestroy() and decide to exit at any moment, so we have to do it + // now and hope that OnDelete() doesn't do anything stupid (or, preferably, + // anything at all). OnDelete(); + m_critsect.Leave(); + switch ( state ) { case STATE_NEW: