From d08d1cbd672cc6e0b62392bed7bde530b1df9bd6 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 26 Nov 2016 00:15:01 +0000 Subject: [PATCH] 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. --- src/linkgraph/linkgraphjob.cpp | 12 ++++++++---- src/linkgraph/linkgraphjob.h | 1 + src/linkgraph/linkgraphschedule.cpp | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index ce3c182e7f..07ed30d947 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -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() { this->JoinThread(); +} - /* Don't update stuff from other pools, when everything is being removed. - * Accessing other pools may be invalid. */ - if (CleaningPool()) return; +/** + * Join the link graph job thread, then merge/apply it. + */ +void LinkGraphJob::FinaliseJob() +{ + this->JoinThread(); /* Link graph has been merged into another one. */ if (!LinkGraph::IsValidID(this->link_graph.index)) return; diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index c5935d405a..7539911807 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -279,6 +279,7 @@ public: ~LinkGraphJob(); void Init(); + void FinaliseJob(); bool IsJobCompleted() const; diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index ea729f4f59..d855a5f602 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -129,7 +129,8 @@ void LinkGraphSchedule::JoinNext() std::unique_ptr next = std::move(this->running.front()); this->running.pop_front(); 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)) { LinkGraph *lg = LinkGraph::Get(id); this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.