fix crash when closing wesnoth during loadingscreen

http://gna.org/bugs/?25290
This commit is contained in:
gfgtdf 2017-03-13 18:55:06 +01:00
parent 6297ede88f
commit bf3c70b9a6
2 changed files with 15 additions and 0 deletions

View file

@ -86,6 +86,7 @@ loading_screen::loading_screen(std::function<void()> f)
, visible_stages_()
, animation_stages_()
, current_visible_stage_()
, is_worker_running_(false)
{
for (const auto& pair : stages) {
visible_stages_[pair.first] = t_string(pair.second, "wesnoth-lib") + "...";
@ -117,12 +118,14 @@ void loading_screen::pre_show(window& window)
{
if (work_) {
worker_.reset(new boost::thread([this]() {
is_worker_running_ = true;
try {
work_();
} catch(...) {
//TODO: guard this with a mutex.
exception_ = std::current_exception();
}
is_worker_running_ = false;
}));
}
timer_id_ = add_timer(100, std::bind(&loading_screen::timer_callback, this, std::ref(window)), true);
@ -194,6 +197,16 @@ void loading_screen::timer_callback(window& window)
loading_screen::~loading_screen()
{
if (is_worker_running_) {
// The worker thread is running, exit the application to prevent memory corruption.
// TODO: this is still not optimal, the main problem is that this code here assumes
// that this happened becasue the window was closed which is not necessarily the case
// (other possibilities migth be a 'dialog doesn't fit on screen' exception casued by resizing the window)
// Another approach migth be to add exit points ( boost::this_thread::interruption_point() ) to the worker
// functions (filesystem.cpp config parsing code etc. ) and then use that to end the thread faster.
std::exit(0);
}
clear_timer();
close();
current_load = nullptr;

View file

@ -94,6 +94,8 @@ private:
std::map<std::string, t_string> visible_stages_;
std::vector<t_string> animation_stages_;
std::map<std::string, t_string>::const_iterator current_visible_stage_;
bool is_worker_running_;
};
} // namespace dialogs