diff options
author | fonsinchen <fonsinchen@openttd.org> | 2014-02-16 18:42:59 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2014-02-16 18:42:59 +0000 |
commit | cc77d4033669da00bd8de17c231fc64a7264c56e (patch) | |
tree | 729b27adbb4709f939d1571c47a505f43022d9c6 | |
parent | 55502341ac4975e2e5bf0661b094fa3d4e7fe890 (diff) | |
download | openttd-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.cpp | 34 | ||||
-rw-r--r-- | src/linkgraph/linkgraphjob.h | 2 | ||||
-rw-r--r-- | src/linkgraph/linkgraphschedule.cpp | 43 | ||||
-rw-r--r-- | src/linkgraph/linkgraphschedule.h | 3 |
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. |