mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-08 23:19:40 +00:00
(svn r26347) -Fix [FS#5898]: Make sure link graph jobs can delete themselves after SLA_NULL.
This commit is contained in:
parent
55502341ac
commit
cc77d40336
@ -13,6 +13,7 @@
|
|||||||
#include "../core/pool_func.hpp"
|
#include "../core/pool_func.hpp"
|
||||||
#include "../window_func.h"
|
#include "../window_func.h"
|
||||||
#include "linkgraphjob.h"
|
#include "linkgraphjob.h"
|
||||||
|
#include "linkgraphschedule.h"
|
||||||
|
|
||||||
/* Initialize the link-graph-job-pool */
|
/* Initialize the link-graph-job-pool */
|
||||||
LinkGraphJobPool _link_graph_job_pool("LinkGraphJob");
|
LinkGraphJobPool _link_graph_job_pool("LinkGraphJob");
|
||||||
@ -45,12 +46,43 @@ 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.
|
* Join the link graph job and destroy it.
|
||||||
*/
|
*/
|
||||||
LinkGraphJob::~LinkGraphJob()
|
LinkGraphJob::~LinkGraphJob()
|
||||||
{
|
{
|
||||||
assert(this->thread == NULL);
|
this->JoinThread();
|
||||||
|
|
||||||
/* Don't update stuff from other pools, when everything is being removed.
|
/* Don't update stuff from other pools, when everything is being removed.
|
||||||
* Accessing other pools may be invalid. */
|
* Accessing other pools may be invalid. */
|
||||||
|
@ -65,6 +65,8 @@ protected:
|
|||||||
EdgeAnnotationMatrix edges; ///< Extra edge data necessary for link graph calculation.
|
EdgeAnnotationMatrix edges; ///< Extra edge data necessary for link graph calculation.
|
||||||
|
|
||||||
void EraseFlows(NodeID from);
|
void EraseFlows(NodeID from);
|
||||||
|
void JoinThread();
|
||||||
|
void SpawnThread();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -16,40 +16,6 @@
|
|||||||
#include "mcf.h"
|
#include "mcf.h"
|
||||||
#include "flowmapper.h"
|
#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.
|
* Start the next job in the schedule.
|
||||||
*/
|
*/
|
||||||
@ -67,7 +33,7 @@ void LinkGraphSchedule::SpawnNext()
|
|||||||
this->schedule.pop_front();
|
this->schedule.pop_front();
|
||||||
if (LinkGraphJob::CanAllocateItem()) {
|
if (LinkGraphJob::CanAllocateItem()) {
|
||||||
LinkGraphJob *job = new LinkGraphJob(*next);
|
LinkGraphJob *job = new LinkGraphJob(*next);
|
||||||
this->SpawnThread(job);
|
job->SpawnThread();
|
||||||
this->running.push_back(job);
|
this->running.push_back(job);
|
||||||
} else {
|
} else {
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
@ -84,8 +50,7 @@ void LinkGraphSchedule::JoinNext()
|
|||||||
if (!next->IsFinished()) return;
|
if (!next->IsFinished()) return;
|
||||||
this->running.pop_front();
|
this->running.pop_front();
|
||||||
LinkGraphID id = next->LinkGraphIndex();
|
LinkGraphID id = next->LinkGraphIndex();
|
||||||
this->JoinThread(next);
|
delete next; // implicitly joins the thread
|
||||||
delete next;
|
|
||||||
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.
|
||||||
@ -114,7 +79,7 @@ void LinkGraphSchedule::JoinNext()
|
|||||||
void LinkGraphSchedule::SpawnAll()
|
void LinkGraphSchedule::SpawnAll()
|
||||||
{
|
{
|
||||||
for (JobList::iterator i = this->running.begin(); i != this->running.end(); ++i) {
|
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();
|
LinkGraphSchedule *inst = LinkGraphSchedule::Instance();
|
||||||
for (JobList::iterator i(inst->running.begin()); i != inst->running.end(); ++i) {
|
for (JobList::iterator i(inst->running.begin()); i != inst->running.end(); ++i) {
|
||||||
inst->JoinThread(*i);
|
(*i)->JoinThread();
|
||||||
}
|
}
|
||||||
inst->running.clear();
|
inst->running.clear();
|
||||||
inst->schedule.clear();
|
inst->schedule.clear();
|
||||||
|
@ -48,9 +48,6 @@ protected:
|
|||||||
GraphList schedule; ///< Queue for new jobs.
|
GraphList schedule; ///< Queue for new jobs.
|
||||||
JobList running; ///< Currently running jobs.
|
JobList running; ///< Currently running jobs.
|
||||||
|
|
||||||
void SpawnThread(LinkGraphJob *job);
|
|
||||||
void JoinThread(LinkGraphJob *job);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* This is a tick where not much else is happening, so a small lag might go unnoticed. */
|
/* 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.
|
static const uint SPAWN_JOIN_TICK = 21; ///< Tick when jobs are spawned or joined every day.
|
||||||
|
Loading…
Reference in New Issue
Block a user