X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d3f8206ce7a28751edbe0610dcd40d54ac6d758d..6fef2483d9dc1a7c006d2f5967791e0f4c0cf518:/src/msw/thread.cpp diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 9a0bdbb46c..ee7fec670d 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -21,23 +21,24 @@ #pragma hdrstop #endif +#if wxUSE_THREADS + +#include "wx/thread.h" + #ifndef WX_PRECOMP + #include "wx/msw/missing.h" #include "wx/intl.h" #include "wx/app.h" + #include "wx/module.h" #endif -#if wxUSE_THREADS - #include "wx/apptrait.h" #include "wx/scopeguard.h" #include "wx/msw/private.h" -#include "wx/msw/missing.h" #include "wx/msw/seh.h" #include "wx/except.h" -#include "wx/module.h" -#include "wx/thread.h" // must have this symbol defined to get _beginthread/_endthread declarations #ifndef _MT @@ -354,14 +355,22 @@ wxSemaError wxSemaphoreInternal::Post() { #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300) if ( !::ReleaseSemaphore(m_semaphore, 1, NULL /* ptr to previous count */) ) -#endif { - wxLogLastError(_T("ReleaseSemaphore")); - - return wxSEMA_MISC_ERROR; + if ( GetLastError() == ERROR_TOO_MANY_POSTS ) + { + return wxSEMA_OVERFLOW; + } + else + { + wxLogLastError(_T("ReleaseSemaphore")); + return wxSEMA_MISC_ERROR; + } } return wxSEMA_NO_ERROR; +#else + return wxSEMA_MISC_ERROR; +#endif } // ---------------------------------------------------------------------------- @@ -436,6 +445,10 @@ public: // really start the thread (if it's not already dead) static THREAD_RETVAL DoThreadStart(wxThread *thread); + // call OnExit() on the thread + static void DoThreadOnExit(wxThread *thread); + + void KeepAlive() { if ( m_thread->IsDetached() ) @@ -477,14 +490,25 @@ private: wxThreadInternal& m_thrImpl; }; +/* static */ +void wxThreadInternal::DoThreadOnExit(wxThread *thread) +{ + wxTRY + { + thread->OnExit(); + } + wxCATCH_ALL( wxTheApp->OnUnhandledException(); ) +} + +/* static */ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread) { + wxON_BLOCK_EXIT1(DoThreadOnExit, thread); + THREAD_RETVAL rc = (THREAD_RETVAL)-1; wxTRY { - wxON_BLOCK_EXIT_OBJ0(*thread, wxThread::OnExit); - // store the thread object in the TLS if ( !::TlsSetValue(gs_tlsThisThread, thread) ) { @@ -500,6 +524,7 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread) return rc; } +/* static */ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param) { THREAD_RETVAL rc = (THREAD_RETVAL)-1; @@ -513,14 +538,16 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param) // start the user code at all then 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); - } - wxSEH_HANDLE((THREAD_RETVAL)-1) } + wxSEH_HANDLE((THREAD_RETVAL)-1) + // save IsDetached because thread object can be deleted by joinable // threads after state is changed to STATE_EXITED. @@ -1363,4 +1390,3 @@ bool WXDLLIMPEXP_BASE wxIsWaitingForThread() #include "wx/thrimpl.cpp" #endif // wxUSE_THREADS -