summaryrefslogtreecommitdiff
path: root/src/mbgl/util/worker.cpp
diff options
context:
space:
mode:
authorJason Wray <jason@kulturny.com>2015-04-27 17:49:24 -0400
committerJason Wray <jason@kulturny.com>2015-04-27 17:49:24 -0400
commit4d631623c7d29e8d40720e521e78c3299995b674 (patch)
treef8495149badf9b0fc76a51d5bde63c8bc375a709 /src/mbgl/util/worker.cpp
parent7ac01660d7efd8ce7939a7934a6f5546e26f6c86 (diff)
parent99ab9c3c6debdf492aff7a751d82400eba1b1cdf (diff)
downloadqtlocation-mapboxgl-4d631623c7d29e8d40720e521e78c3299995b674.tar.gz
Merge master @ 353e5661de
Diffstat (limited to 'src/mbgl/util/worker.cpp')
-rw-r--r--src/mbgl/util/worker.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp
new file mode 100644
index 0000000000..3559cdd71f
--- /dev/null
+++ b/src/mbgl/util/worker.cpp
@@ -0,0 +1,73 @@
+#include <mbgl/util/worker.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+
+Worker::Worker(uv_loop_t* loop, std::size_t count)
+ : queue(new Queue(loop, [this](Fn after) { afterWork(after); }))
+{
+ queue->unref();
+
+ for (std::size_t i = 0; i < count; i++) {
+ threads.emplace_back(&Worker::workLoop, this);
+ }
+}
+
+Worker::~Worker() {
+ MBGL_VERIFY_THREAD(tid);
+
+ if (active++ == 0) {
+ queue->ref();
+ }
+
+ channel.send(Work());
+
+ for (auto& thread : threads) {
+ thread.join();
+ }
+
+ queue->stop();
+}
+
+void Worker::send(Fn work, Fn after) {
+ MBGL_VERIFY_THREAD(tid);
+ assert(work);
+
+ if (active++ == 0) {
+ queue->ref();
+ }
+
+ channel.send({work, after});
+}
+
+void Worker::workLoop() {
+#ifdef __APPLE__
+ pthread_setname_np("Worker");
+#endif
+
+ while (true) {
+ Work item = channel.receive();
+
+ if (!item.work)
+ break;
+
+ item.work();
+ queue->send(std::move(item.after));
+ }
+
+ // Make sure to close all other workers too.
+ channel.send(Work());
+}
+
+void Worker::afterWork(Fn after) {
+ if (after) {
+ after();
+ }
+
+ if (--active == 0) {
+ queue->unref();
+ }
+}
+
+}