Linkgraph: Avoid attempting to merge/apply job when cleaning schedule.

This can cause crashes when switching savegame.
Move job merge/apply out of destructor into separate function.
This commit is contained in:
Jonathan G Rennison
2016-11-26 00:15:01 +00:00
parent e1a841aa05
commit d08d1cbd67
3 changed files with 11 additions and 5 deletions

View File

@@ -82,15 +82,19 @@ void LinkGraphJob::JoinThread()
} }
/** /**
* Join the link graph job and destroy it. * Join the link graph job thread, if not already joined.
*/ */
LinkGraphJob::~LinkGraphJob() LinkGraphJob::~LinkGraphJob()
{ {
this->JoinThread(); this->JoinThread();
}
/* Don't update stuff from other pools, when everything is being removed. /**
* Accessing other pools may be invalid. */ * Join the link graph job thread, then merge/apply it.
if (CleaningPool()) return; */
void LinkGraphJob::FinaliseJob()
{
this->JoinThread();
/* Link graph has been merged into another one. */ /* Link graph has been merged into another one. */
if (!LinkGraph::IsValidID(this->link_graph.index)) return; if (!LinkGraph::IsValidID(this->link_graph.index)) return;

View File

@@ -279,6 +279,7 @@ public:
~LinkGraphJob(); ~LinkGraphJob();
void Init(); void Init();
void FinaliseJob();
bool IsJobCompleted() const; bool IsJobCompleted() const;

View File

@@ -129,7 +129,8 @@ void LinkGraphSchedule::JoinNext()
std::unique_ptr<LinkGraphJob> next = std::move(this->running.front()); std::unique_ptr<LinkGraphJob> next = std::move(this->running.front());
this->running.pop_front(); this->running.pop_front();
LinkGraphID id = next->LinkGraphIndex(); LinkGraphID id = next->LinkGraphIndex();
next.reset(); // implicitly joins the thread next->FinaliseJob(); // joins the thread and finalises the job
next.reset();
if (LinkGraph::IsValidID(id)) { if (LinkGraph::IsValidID(id)) {
LinkGraph *lg = LinkGraph::Get(id); LinkGraph *lg = LinkGraph::Get(id);
this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs. this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.