Factor out exception handling code in a new WXConsumeException()
This will allow using this code from other places and not only when executing user-defined event handlers. No changes in this commit yet.
This commit is contained in:
@@ -3386,6 +3386,18 @@ public:
|
|||||||
// NOTE: uses AddPendingEvent(); call only from secondary threads
|
// NOTE: uses AddPendingEvent(); call only from secondary threads
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_EXCEPTIONS
|
||||||
|
// This is a private function which handles any exceptions arising during
|
||||||
|
// the execution of user-defined code called in the event loop context by
|
||||||
|
// forwarding them to wxApp::OnExceptionInMainLoop() and, if it rethrows,
|
||||||
|
// to wxApp::OnUnhandledException(). In any case this function ensures that
|
||||||
|
// no exceptions ever escape from it and so is useful to call at module
|
||||||
|
// boundary.
|
||||||
|
//
|
||||||
|
// It must be only called when handling an active exception.
|
||||||
|
static void WXConsumeException();
|
||||||
|
#endif // wxUSE_EXCEPTIONS
|
||||||
|
|
||||||
#ifdef wxHAS_CALL_AFTER
|
#ifdef wxHAS_CALL_AFTER
|
||||||
// Asynchronous method calls: these methods schedule the given method
|
// Asynchronous method calls: these methods schedule the given method
|
||||||
// pointer for a later call (during the next idle event loop iteration).
|
// pointer for a later call (during the next idle event loop iteration).
|
||||||
|
@@ -1604,70 +1604,79 @@ bool wxEvtHandler::SafelyProcessEvent(wxEvent& event)
|
|||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
|
WXConsumeException();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // wxUSE_EXCEPTIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_EXCEPTIONS
|
||||||
|
/* static */
|
||||||
|
void wxEvtHandler::WXConsumeException()
|
||||||
|
{
|
||||||
|
wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() )
|
||||||
|
{
|
||||||
|
if ( loop )
|
||||||
|
loop->Exit();
|
||||||
|
}
|
||||||
|
//else: continue running current event loop
|
||||||
|
}
|
||||||
|
catch ( ... )
|
||||||
|
{
|
||||||
|
// OnExceptionInMainLoop() threw, possibly rethrowing the same
|
||||||
|
// exception again. We have to deal with it here because we can't
|
||||||
|
// allow the exception to escape from the handling code, this will
|
||||||
|
// result in a crash at best (e.g. when using wxGTK as C++
|
||||||
|
// exceptions can't propagate through the C GTK+ code and corrupt
|
||||||
|
// the stack) and in something even more weird at worst (like
|
||||||
|
// exceptions completely disappearing into the void under some
|
||||||
|
// 64 bit versions of Windows).
|
||||||
|
if ( loop && !loop->IsYielding() )
|
||||||
|
loop->Exit();
|
||||||
|
|
||||||
|
// Give the application one last possibility to store the exception
|
||||||
|
// for rethrowing it later, when we get back to our code.
|
||||||
|
bool stored = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() )
|
if ( wxTheApp )
|
||||||
{
|
stored = wxTheApp->StoreCurrentException();
|
||||||
if ( loop )
|
|
||||||
loop->Exit();
|
|
||||||
}
|
|
||||||
//else: continue running current event loop
|
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
// OnExceptionInMainLoop() threw, possibly rethrowing the same
|
// StoreCurrentException() really shouldn't throw, but if it
|
||||||
// exception again. We have to deal with it here because we can't
|
// did, take it as an indication that it didn't store it.
|
||||||
// allow the exception to escape from the handling code, this will
|
}
|
||||||
// result in a crash at best (e.g. when using wxGTK as C++
|
|
||||||
// exceptions can't propagate through the C GTK+ code and corrupt
|
|
||||||
// the stack) and in something even more weird at worst (like
|
|
||||||
// exceptions completely disappearing into the void under some
|
|
||||||
// 64 bit versions of Windows).
|
|
||||||
if ( loop && !loop->IsYielding() )
|
|
||||||
loop->Exit();
|
|
||||||
|
|
||||||
// Give the application one last possibility to store the exception
|
// If it didn't take it, just abort, at least like this we behave
|
||||||
// for rethrowing it later, when we get back to our code.
|
// consistently everywhere.
|
||||||
bool stored = false;
|
if ( !stored )
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ( wxTheApp )
|
if ( wxTheApp )
|
||||||
stored = wxTheApp->StoreCurrentException();
|
wxTheApp->OnUnhandledException();
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
// StoreCurrentException() really shouldn't throw, but if it
|
// And OnUnhandledException() absolutely shouldn't throw,
|
||||||
// did, take it as an indication that it didn't store it.
|
// but we still must account for the possibility that it
|
||||||
|
// did. At least show some information about the exception
|
||||||
|
// in this case.
|
||||||
|
wxTheApp->wxAppConsoleBase::OnUnhandledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it didn't take it, just abort, at least like this we behave
|
wxAbort();
|
||||||
// consistently everywhere.
|
|
||||||
if ( !stored )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if ( wxTheApp )
|
|
||||||
wxTheApp->OnUnhandledException();
|
|
||||||
}
|
|
||||||
catch ( ... )
|
|
||||||
{
|
|
||||||
// And OnUnhandledException() absolutely shouldn't throw,
|
|
||||||
// but we still must account for the possibility that it
|
|
||||||
// did. At least show some information about the exception
|
|
||||||
// in this case.
|
|
||||||
wxTheApp->wxAppConsoleBase::OnUnhandledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxAbort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
#endif // wxUSE_EXCEPTIONS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_EXCEPTIONS
|
||||||
|
|
||||||
bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
|
bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
|
||||||
{
|
{
|
||||||
const wxEventType eventType = event.GetEventType();
|
const wxEventType eventType = event.GetEventType();
|
||||||
|
Reference in New Issue
Block a user