Pass exceptions in async workers back to the main thread

This commit is contained in:
Thomas Goyne 2014-05-09 06:30:07 -07:00
parent 74e995b915
commit eadf555da3
2 changed files with 28 additions and 15 deletions

View File

@ -91,7 +91,15 @@ void Init(std::function<void (Thunk)> invoke_main) {
} }
void Queue::Async(Thunk thunk) { 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) { void Queue::Sync(Thunk thunk) {

View File

@ -127,18 +127,18 @@ bool AegisubApp::OnInit() {
using codecvt = std::codecvt<wchar_t, char, std::mbstate_t>; using codecvt = std::codecvt<wchar_t, char, std::mbstate_t>;
int result = std::codecvt_base::error; int result = std::codecvt_base::error;
if (std::has_facet<codecvt>(locale)) { if (std::has_facet<codecvt>(locale)) {
wchar_t test[] = L"\xFFFE"; wchar_t test[] = L"\xFFFE";
char buff[8]; char buff[8];
auto mb = std::mbstate_t(); auto mb = std::mbstate_t();
const wchar_t* from_next; const wchar_t* from_next;
char* to_next; char* to_next;
result = std::use_facet<codecvt>(locale).out(mb, result = std::use_facet<codecvt>(locale).out(mb,
test, std::end(test), from_next, test, std::end(test), from_next,
buff, std::end(buff), to_next); buff, std::end(buff), to_next);
} }
// If we didn't get a UTF-8 locale, force it to a known one // If we didn't get a UTF-8 locale, force it to a known one
if (result != std::codecvt_base::ok) if (result != std::codecvt_base::ok)
locale = boost::locale::generator().generate("en_US.UTF-8"); locale = boost::locale::generator().generate("en_US.UTF-8");
std::locale::global(locale); std::locale::global(locale);
} }
@ -152,8 +152,13 @@ bool AegisubApp::OnInit() {
wxTheApp->QueueEvent(evt); wxTheApp->QueueEvent(evt);
}); });
wxTheApp->Bind(EVT_CALL_THUNK, [](wxThreadEvent &evt) { wxTheApp->Bind(EVT_CALL_THUNK, [this](wxThreadEvent &evt) {
evt.GetPayload<std::function<void()>>()(); try {
evt.GetPayload<std::function<void()>>()();
}
catch (...) {
OnExceptionInMainLoop();
}
}); });
config::path = new agi::Path; config::path = new agi::Path;