rethrow exceptions form loadingscreen worker thread

fixed crashes during loadingsceeen in case of bad wml as noted
in  https://gna.org/bugs/?24928
This commit is contained in:
gfgtdf 2016-08-06 15:20:54 +02:00
parent e6b31636c1
commit 6a32d984fd
2 changed files with 24 additions and 2 deletions

View file

@ -107,7 +107,15 @@ twindow* tloadscreen::build_window(CVideo& video) const
void tloadscreen::pre_show(twindow& window)
{
if (work_) {
worker_.reset(new boost::thread(work_));
worker_.reset(new boost::thread([this]() {
try {
work_();
}
catch (const game::error&) {
//TODO: guard this with a mutex.
exception_ = std::current_exception();
}
}));
}
timer_id_ = add_timer(100, std::bind(&tloadscreen::timer_callback, this, std::ref(window)), true);
cursor_setter_.reset(new cursor::setter(cursor::WAIT));
@ -121,7 +129,7 @@ void tloadscreen::pre_show(twindow& window)
void tloadscreen::post_show(twindow& /*window*/)
{
worker_.reset();
remove_timer(timer_id_);
clear_timer();
cursor_setter_.reset();
}
@ -145,6 +153,10 @@ tloadscreen* tloadscreen::current_load = nullptr;
void tloadscreen::timer_callback(twindow& window)
{
if (!work_ || !worker_ || worker_->timed_join(boost::posix_time::milliseconds(0))) {
if (exception_) {
clear_timer();
std::rethrow_exception(exception_);
}
window.close();
}
if (!work_) {
@ -174,6 +186,7 @@ void tloadscreen::timer_callback(twindow& window)
tloadscreen::~tloadscreen()
{
clear_timer();
close();
current_load = nullptr;
}
@ -192,5 +205,12 @@ void tloadscreen::display(CVideo& video, std::function<void()> f)
f();
}
}
void tloadscreen::clear_timer()
{
if (timer_id_ != 0) {
remove_timer(timer_id_);
timer_id_ = 0;
}
}
} // namespace gui2

View file

@ -62,6 +62,8 @@ private:
std::function<void()> work_;
std::unique_ptr<boost::thread> worker_;
std::unique_ptr<cursor::setter> cursor_setter_;
std::exception_ptr exception_;
void clear_timer();
twindow* build_window(CVideo& video) const;