diff --git a/common/include/Utilities/PersistentThread.h b/common/include/Utilities/PersistentThread.h index 33aa5c560d..cb2235bf8f 100644 --- a/common/include/Utilities/PersistentThread.h +++ b/common/include/Utilities/PersistentThread.h @@ -200,6 +200,7 @@ protected: void _ThreadCleanup(); static void *_internal_callback(void *func); + static void internal_callback_helper(void *func); static void _pt_callback_cleanup(void *handle); }; } diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index d7135e34f9..f22cc2dba6 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -685,12 +685,21 @@ void *Threading::pxThread::_internal_callback(void *itsme) { if (!pxAssertDev(itsme != NULL, wxNullChar)) return NULL; - pxThread &owner = *((pxThread *)itsme); + + internal_callback_helper(itsme); + return nullptr; +} + +// __try is used in pthread_cleanup_push when CLEANUP_SEH is used as the cleanup model. +// That can't be used in a function that has objects that require unwinding (compile +// error C2712), so move it into a separate function. +void Threading::pxThread::internal_callback_helper(void *itsme) +{ + pxThread &owner = *static_cast(itsme); pthread_cleanup_push(_pt_callback_cleanup, itsme); owner._internal_execute(); pthread_cleanup_pop(true); - return NULL; } void Threading::pxThread::_DoSetThreadName(const wxString &name)