From eadf555da3874f235b59eb9855b73c81e6f19440 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 9 May 2014 06:30:07 -0700 Subject: [PATCH] Pass exceptions in async workers back to the main thread --- libaegisub/common/dispatch.cpp | 10 +++++++++- src/main.cpp | 33 +++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/libaegisub/common/dispatch.cpp b/libaegisub/common/dispatch.cpp index 509dc93ea..434195836 100644 --- a/libaegisub/common/dispatch.cpp +++ b/libaegisub/common/dispatch.cpp @@ -91,7 +91,15 @@ void Init(std::function invoke_main) { } void Queue::Async(Thunk thunk) { - DoInvoke(thunk); + DoInvoke([=] { + try { + thunk(); + } + catch (...) { + auto e = std::current_exception(); + invoke_main([=] { std::rethrow_exception(e); }); + } + }); } void Queue::Sync(Thunk thunk) { diff --git a/src/main.cpp b/src/main.cpp index c8d0dbfca..9bc305bb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -127,18 +127,18 @@ bool AegisubApp::OnInit() { using codecvt = std::codecvt; int result = std::codecvt_base::error; if (std::has_facet(locale)) { - wchar_t test[] = L"\xFFFE"; - char buff[8]; - auto mb = std::mbstate_t(); - const wchar_t* from_next; - char* to_next; - result = std::use_facet(locale).out(mb, - test, std::end(test), from_next, - buff, std::end(buff), to_next); - } - - // If we didn't get a UTF-8 locale, force it to a known one - if (result != std::codecvt_base::ok) + wchar_t test[] = L"\xFFFE"; + char buff[8]; + auto mb = std::mbstate_t(); + const wchar_t* from_next; + char* to_next; + result = std::use_facet(locale).out(mb, + test, std::end(test), from_next, + buff, std::end(buff), to_next); + } + + // If we didn't get a UTF-8 locale, force it to a known one + if (result != std::codecvt_base::ok) locale = boost::locale::generator().generate("en_US.UTF-8"); std::locale::global(locale); } @@ -152,8 +152,13 @@ bool AegisubApp::OnInit() { wxTheApp->QueueEvent(evt); }); - wxTheApp->Bind(EVT_CALL_THUNK, [](wxThreadEvent &evt) { - evt.GetPayload>()(); + wxTheApp->Bind(EVT_CALL_THUNK, [this](wxThreadEvent &evt) { + try { + evt.GetPayload>()(); + } + catch (...) { + OnExceptionInMainLoop(); + } }); config::path = new agi::Path;