summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2014-02-16 18:42:59 +0000
committerfonsinchen <fonsinchen@openttd.org>2014-02-16 18:42:59 +0000
commitcc77d4033669da00bd8de17c231fc64a7264c56e (patch)
tree729b27adbb4709f939d1571c47a505f43022d9c6
parent55502341ac4975e2e5bf0661b094fa3d4e7fe890 (diff)
downloadopenttd-cc77d4033669da00bd8de17c231fc64a7264c56e.tar.xz
(svn r26347) -Fix [FS#5898]: Make sure link graph jobs can delete themselves after SLA_NULL.
-rw-r--r--src/linkgraph/linkgraphjob.cpp34
-rw-r--r--src/linkgraph/linkgraphjob.h2
-rw-r--r--src/linkgraph/linkgraphschedule.cpp43
-rw-r--r--src/linkgraph/linkgraphschedule.h3
4 files changed, 39 insertions, 43 deletions
diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp
index cd00d5fa7..61e313616 100644
--- a/src/linkgraph/linkgraphjob.cpp
+++ b/src/linkgraph/linkgraphjob.cpp
@@ -13,6 +13,7 @@
#include "../core/pool_func.hpp"
#include "../window_func.h"
#include "linkgraphjob.h"
+#include "linkgraphschedule.h"
/* Initialize the link-graph-job-pool */
LinkGraphJobPool _link_graph_job_pool("LinkGraphJob");
@@ -46,11 +47,42 @@ void LinkGraphJob::EraseFlows(NodeID from)
}
/**
+ * Spawn a thread if possible and run the link graph job in the thread. If
+ * that's not possible run the job right now in the current thread.
+ */
+void LinkGraphJob::SpawnThread()
+{
+ if (!ThreadObject::New(&(LinkGraphSchedule::Run), this, &this->thread)) {
+ this->thread = NULL;
+ /* Of course this will hang a bit.
+ * On the other hand, if you want to play games which make this hang noticably
+ * on a platform without threads then you'll probably get other problems first.
+ * OK:
+ * If someone comes and tells me that this hangs for him/her, I'll implement a
+ * smaller grained "Step" method for all handlers and add some more ticks where
+ * "Step" is called. No problem in principle. */
+ LinkGraphSchedule::Run(this);
+ }
+}
+
+/**
+ * Join the calling thread with this job's thread if threading is enabled.
+ */
+void LinkGraphJob::JoinThread()
+{
+ if (this->thread != NULL) {
+ this->thread->Join();
+ delete this->thread;
+ this->thread = NULL;
+ }
+}
+
+/**
* Join the link graph job and destroy it.
*/
LinkGraphJob::~LinkGraphJob()
{
- assert(this->thread == NULL);
+ this->JoinThread();
/* Don't update stuff from other pools, when everything is being removed.
* Accessing other pools may be invalid. */
diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h
index 130379220..00b65f208 100644
--- a/src/linkgraph/linkgraphjob.h
+++ b/src/linkgraph/linkgraphjob.h
@@ -65,6 +65,8 @@ protected:
EdgeAnnotationMatrix edges; ///< Extra edge data necessary for link graph calculation.
void EraseFlows(NodeID from);
+ void JoinThread();
+ void SpawnThread();
public:
diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp
index b3e6fac2f..4e6f33266 100644
--- a/src/linkgraph/linkgraphschedule.cpp
+++ b/src/linkgraph/linkgraphschedule.cpp
@@ -17,40 +17,6 @@
#include "flowmapper.h"
/**
- * Spawn a thread if possible and run the link graph job in the thread. If
- * that's not possible run the job right now in the current thread.
- * @param job Job to be executed.
- */
-void LinkGraphSchedule::SpawnThread(LinkGraphJob *job)
-{
- if (!ThreadObject::New(&(LinkGraphSchedule::Run), job, &job->thread)) {
- job->thread = NULL;
- /* Of course this will hang a bit.
- * On the other hand, if you want to play games which make this hang noticably
- * on a platform without threads then you'll probably get other problems first.
- * OK:
- * If someone comes and tells me that this hangs for him/her, I'll implement a
- * smaller grained "Step" method for all handlers and add some more ticks where
- * "Step" is called. No problem in principle.
- */
- LinkGraphSchedule::Run(job);
- }
-}
-
-/**
- * Join the calling thread with the given job's thread if threading is enabled.
- * @param job Job whose execution thread is to be joined.
- */
-void LinkGraphSchedule::JoinThread(LinkGraphJob *job)
-{
- if (job->thread != NULL) {
- job->thread->Join();
- delete job->thread;
- job->thread = NULL;
- }
-}
-
-/**
* Start the next job in the schedule.
*/
void LinkGraphSchedule::SpawnNext()
@@ -67,7 +33,7 @@ void LinkGraphSchedule::SpawnNext()
this->schedule.pop_front();
if (LinkGraphJob::CanAllocateItem()) {
LinkGraphJob *job = new LinkGraphJob(*next);
- this->SpawnThread(job);
+ job->SpawnThread();
this->running.push_back(job);
} else {
NOT_REACHED();
@@ -84,8 +50,7 @@ void LinkGraphSchedule::JoinNext()
if (!next->IsFinished()) return;
this->running.pop_front();
LinkGraphID id = next->LinkGraphIndex();
- this->JoinThread(next);
- delete next;
+ delete next; // implicitly joins the thread
if (LinkGraph::IsValidID(id)) {
LinkGraph *lg = LinkGraph::Get(id);
this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.
@@ -114,7 +79,7 @@ void LinkGraphSchedule::JoinNext()
void LinkGraphSchedule::SpawnAll()
{
for (JobList::iterator i = this->running.begin(); i != this->running.end(); ++i) {
- this->SpawnThread(*i);
+ (*i)->SpawnThread();
}
}
@@ -125,7 +90,7 @@ void LinkGraphSchedule::SpawnAll()
{
LinkGraphSchedule *inst = LinkGraphSchedule::Instance();
for (JobList::iterator i(inst->running.begin()); i != inst->running.end(); ++i) {
- inst->JoinThread(*i);
+ (*i)->JoinThread();
}
inst->running.clear();
inst->schedule.clear();
diff --git a/src/linkgraph/linkgraphschedule.h b/src/linkgraph/linkgraphschedule.h
index 25c56904f..5d1871962 100644
--- a/src/linkgraph/linkgraphschedule.h
+++ b/src/linkgraph/linkgraphschedule.h
@@ -48,9 +48,6 @@ protected:
GraphList schedule; ///< Queue for new jobs.
JobList running; ///< Currently running jobs.
- void SpawnThread(LinkGraphJob *job);
- void JoinThread(LinkGraphJob *job);
-
public:
/* This is a tick where not much else is happening, so a small lag might go unnoticed. */
static const uint SPAWN_JOIN_TICK = 21; ///< Tick when jobs are spawned or joined every day.