summaryrefslogtreecommitdiff
path: root/src/linkgraph/linkgraphschedule.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/linkgraph/linkgraphschedule.h')
-rw-r--r--src/linkgraph/linkgraphschedule.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/linkgraph/linkgraphschedule.h b/src/linkgraph/linkgraphschedule.h
new file mode 100644
index 000000000..3b71f2954
--- /dev/null
+++ b/src/linkgraph/linkgraphschedule.h
@@ -0,0 +1,83 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file linkgraphschedule.h Declaration of link graph schedule used for cargo distribution. */
+
+#ifndef LINKGRAPHSCHEDULE_H
+#define LINKGRAPHSCHEDULE_H
+
+#include "linkgraph.h"
+
+class LinkGraphJob;
+
+/**
+ * A handler doing "something" on a link graph component. It must not keep any
+ * state as it is called concurrently from different threads.
+ */
+class ComponentHandler {
+public:
+ /**
+ * Destroy the handler. Must be given due to virtual Run.
+ */
+ virtual ~ComponentHandler() {}
+
+ /**
+ * Run the handler. A link graph handler must not read or write any data
+ * outside the given component as that would create a potential desync.
+ * @param job Link graph component to run the handler on.
+ */
+ virtual void Run(LinkGraphJob &job) const = 0;
+};
+
+class LinkGraphSchedule {
+private:
+ LinkGraphSchedule();
+ ~LinkGraphSchedule();
+ typedef std::list<LinkGraph *> GraphList;
+ typedef std::list<LinkGraphJob *> JobList;
+ friend const SaveLoad *GetLinkGraphScheduleDesc();
+
+protected:
+ ComponentHandler *handlers[1]; ///< Handlers to be run for each job.
+ 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.
+
+ static LinkGraphSchedule *Instance();
+ static void Run(void *j);
+ static void Clear();
+
+ void SpawnNext();
+ void JoinNext();
+ void SpawnAll();
+
+ /**
+ * Queue a link graph for execution.
+ * @param lg Link graph to be queued.
+ */
+ void Queue(LinkGraph *lg)
+ {
+ assert(LinkGraph::Get(lg->index) == lg);
+ this->schedule.push_back(lg);
+ }
+
+ /**
+ * Remove a link graph from the execution queue.
+ * @param lg Link graph to be removed.
+ */
+ void Unqueue(LinkGraph *lg) { this->schedule.remove(lg); }
+};
+
+#endif /* LINKGRAPHSCHEDULE_H */