+ // have to declare this before pthread_cleanup_push() which defines a
+ // block!
+ bool dontRunAtAll;
+
+#ifdef wxHAVE_PTHREAD_CLEANUP
+ // install the cleanup handler which will be called if the thread is
+ // cancelled
+ pthread_cleanup_push(wxPthreadCleanup, thread);
+#endif // wxHAVE_PTHREAD_CLEANUP
+
+ // wait for the semaphore to be posted from Run()
+ pthread->m_semRun.Wait();
+
+ // test whether we should run the run at all - may be it was deleted
+ // before it started to Run()?
+ {
+ wxCriticalSectionLocker lock(thread->m_critsect);
+
+ dontRunAtAll = pthread->GetState() == STATE_NEW &&
+ pthread->WasCancelled();
+ }
+
+ if ( !dontRunAtAll )
+ {
+ // call the main entry
+ wxLogTrace(TRACE_THREADS,
+ wxT("Thread %p about to enter its Entry()."),
+ THR_ID(pthread));
+
+ wxTRY
+ {
+ pthread->m_exitcode = thread->Entry();
+
+ wxLogTrace(TRACE_THREADS,
+ wxT("Thread %p Entry() returned %lu."),
+ THR_ID(pthread), wxPtrToUInt(pthread->m_exitcode));
+ }
+#ifdef HAVE_ABI_FORCEDUNWIND
+ // When using common C++ ABI under Linux we must always rethrow this
+ // special exception used to unwind the stack when the thread was
+ // cancelled, otherwise the thread library would simply terminate the
+ // program, see http://udrepper.livejournal.com/21541.html
+ catch ( abi::__forced_unwind& )
+ {
+ wxCriticalSectionLocker lock(thread->m_critsect);
+ pthread->SetState(STATE_EXITED);
+ throw;
+ }
+#endif // HAVE_ABI_FORCEDUNWIND
+ wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
+
+ {
+ wxCriticalSectionLocker lock(thread->m_critsect);
+
+ // change the state of the thread to "exited" so that
+ // wxPthreadCleanup handler won't do anything from now (if it's
+ // called before we do pthread_cleanup_pop below)
+ pthread->SetState(STATE_EXITED);
+ }
+ }