correction to exception handling in threads: call wxThread::OnExit() always

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38936 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-04-27 11:31:21 +00:00
parent 120b9b056e
commit 5b53617d42

View File

@@ -436,6 +436,10 @@ public:
// really start the thread (if it's not already dead) // really start the thread (if it's not already dead)
static THREAD_RETVAL DoThreadStart(wxThread *thread); static THREAD_RETVAL DoThreadStart(wxThread *thread);
// call OnExit() on the thread
static void DoThreadOnExit(wxThread *thread);
void KeepAlive() void KeepAlive()
{ {
if ( m_thread->IsDetached() ) if ( m_thread->IsDetached() )
@@ -477,14 +481,25 @@ private:
wxThreadInternal& m_thrImpl; wxThreadInternal& m_thrImpl;
}; };
/* static */
void wxThreadInternal::DoThreadOnExit(wxThread *thread)
{
wxTRY
{
thread->OnExit();
}
wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
}
/* static */
THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread) THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread)
{ {
wxON_BLOCK_EXIT1(DoThreadOnExit, thread);
THREAD_RETVAL rc = (THREAD_RETVAL)-1; THREAD_RETVAL rc = (THREAD_RETVAL)-1;
wxTRY wxTRY
{ {
wxON_BLOCK_EXIT_OBJ0(*thread, wxThread::OnExit);
// store the thread object in the TLS // store the thread object in the TLS
if ( !::TlsSetValue(gs_tlsThisThread, thread) ) if ( !::TlsSetValue(gs_tlsThisThread, thread) )
{ {
@@ -500,6 +515,7 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread)
return rc; return rc;
} }
/* static */
THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param) THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
{ {
THREAD_RETVAL rc = (THREAD_RETVAL)-1; THREAD_RETVAL rc = (THREAD_RETVAL)-1;
@@ -513,14 +529,16 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
// start the user code at all then // start the user code at all then
const bool hasExited = thread->m_internal->GetState() == STATE_EXITED; const bool hasExited = thread->m_internal->GetState() == STATE_EXITED;
if ( !hasExited ) // run the thread function itself inside a SEH try/except block
wxSEH_TRY
{ {
wxSEH_TRY if ( hasExited )
{ DoThreadOnExit(thread);
else
rc = DoThreadStart(thread); rc = DoThreadStart(thread);
}
wxSEH_HANDLE((THREAD_RETVAL)-1)
} }
wxSEH_HANDLE((THREAD_RETVAL)-1)
// save IsDetached because thread object can be deleted by joinable // save IsDetached because thread object can be deleted by joinable
// threads after state is changed to STATE_EXITED. // threads after state is changed to STATE_EXITED.