diff options
author | Jonathan G Rennison <j.g.rennison@gmail.com> | 2020-12-24 23:36:36 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-25 00:36:36 +0100 |
commit | 94d629d79bcd623a5c77daa3db742cd8fd43d7b4 (patch) | |
tree | 25691cf3b5a2babd913b350275e8753b6b053ce4 /src/linkgraph/linkgraphjob.h | |
parent | ad47e3d9e6d07e5ee60a53ff53a8671058680da7 (diff) | |
download | openttd-94d629d79bcd623a5c77daa3db742cd8fd43d7b4.tar.xz |
Change: [Linkgraph] Allow job threads to be aborted early when clearing schedule (#8416)
When link graph jobs are cleared due to abandoning the game or exiting,
flag the job as aborted.
The link graph job running in a separate thread checks the aborted flag
periodically and terminates processing early if set.
This reduces the delay at game abandon or exit if a long-running job
would otherwise still be running.
Diffstat (limited to 'src/linkgraph/linkgraphjob.h')
-rw-r--r-- | src/linkgraph/linkgraphjob.h | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index ab5e07fb1..764365921 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -63,6 +63,7 @@ protected: NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation. EdgeAnnotationMatrix edges; ///< Extra edge data necessary for link graph calculation. std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale. + std::atomic<bool> job_aborted; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale. void EraseFlows(NodeID from); void JoinThread(); @@ -267,7 +268,7 @@ public: * settings have to be brutally const-casted in order to populate them. */ LinkGraphJob() : settings(_settings_game.linkgraph), - join_date(INVALID_DATE), job_completed(false) {} + join_date(INVALID_DATE), job_completed(false), job_aborted(false) {} LinkGraphJob(const LinkGraph &orig); ~LinkGraphJob(); @@ -282,6 +283,21 @@ public: inline bool IsJobCompleted() const { return this->job_completed.load(std::memory_order_acquire); } /** + * Check if job has been aborted. + * This is allowed to spuriously return false incorrectly, but is not allowed to incorrectly return true. + * @return True if job has been aborted. + */ + inline bool IsJobAborted() const { return this->job_aborted.load(std::memory_order_acquire); } + + /** + * Abort job. + * The job may exit early at the next available opportunity. + * After this method has been called the state of the job is undefined, and the only valid operation + * is to join the thread and discard the job data. + */ + inline void AbortJob() { this->job_aborted.store(true, std::memory_order_release); } + + /** * Check if job is supposed to be finished. * @return True if job should be finished by now, false if not. */ |