+    if ( !dontRunAtAll )
+    {
+        // call the main entry
+        wxLogTrace(TRACE_THREADS, _T("Thread %ld about to enter its Entry()."),
+#ifdef __VMS
+                   (long long)pthread->GetId());
+#else
+                   (long)pthread->GetId());
+#endif
+       
+        pthread->m_exitcode = thread->Entry();
+
+        wxLogTrace(TRACE_THREADS, _T("Thread %ld Entry() returned %lu."),
+#ifdef __VMS
+                   (long long)pthread->GetId(), (unsigned long)pthread->m_exitcode);
+#else
+                   (long)pthread->GetId(), (unsigned long)pthread->m_exitcode);
+#endif
+       
+        {
+            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);
+        }
+    }
+
+    // NB: at least under Linux, pthread_cleanup_push/pop are macros and pop
+    //     contains the matching '}' for the '{' in push, so they must be used
+    //     in the same block!
+#if HAVE_THREAD_CLEANUP_FUNCTIONS
+    // remove the cleanup handler without executing it
+    pthread_cleanup_pop(FALSE);
+#endif // HAVE_THREAD_CLEANUP_FUNCTIONS
+
+    if ( dontRunAtAll )
+    {
+        // FIXME: deleting a possibly joinable thread here???
+        delete thread;
+
+        return EXITCODE_CANCELLED;
+    }
+    else
+    {
+        // terminate the thread
+        thread->Exit(pthread->m_exitcode);
+
+        wxFAIL_MSG(wxT("wxThread::Exit() can't return."));
+
+        return NULL;
+    }
+}
+
+#if HAVE_THREAD_CLEANUP_FUNCTIONS
+
+// this handler is called when the thread is cancelled
+extern "C" void wxPthreadCleanup(void *ptr)
+{
+    wxThreadInternal::Cleanup((wxThread *)ptr);
+}
+
+void wxThreadInternal::Cleanup(wxThread *thread)
+{
+    {
+        wxCriticalSectionLocker lock(thread->m_critsect);
+        if ( thread->m_internal->GetState() == STATE_EXITED )
+        {
+            // thread is already considered as finished.
+            return;
+        }
+    }