summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-09-01 11:09:19 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-12-01 00:00:09 +0200
commitd422c8cac4e436fb2fb1eeafbae5ed5d847e0b00 (patch)
treedd8efd2cd842820f3f13fddf40cc0039fb261363 /platform
parent1d623322044c4650bb39c9224f596341a23f490f (diff)
downloadqtlocation-mapboxgl-d422c8cac4e436fb2fb1eeafbae5ed5d847e0b00.tar.gz
[core] Abstract main loop inside RunLoop class
Diffstat (limited to 'platform')
-rw-r--r--platform/default/async_task.cpp2
-rw-r--r--platform/default/run_loop.cpp83
-rw-r--r--platform/node/src/node_mapbox_gl_native.cpp2
3 files changed, 85 insertions, 2 deletions
diff --git a/platform/default/async_task.cpp b/platform/default/async_task.cpp
index 4b4372451c..1f2381f716 100644
--- a/platform/default/async_task.cpp
+++ b/platform/default/async_task.cpp
@@ -12,7 +12,7 @@ namespace util {
class AsyncTask::Impl {
public:
Impl(std::function<void()>&& fn)
- : async(RunLoop::getLoop(), [this] { runTask(); })
+ : async(reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle()), [this] { runTask(); })
, task(std::move(fn)) {
}
diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp
new file mode 100644
index 0000000000..7c3a74f2cb
--- /dev/null
+++ b/platform/default/run_loop.cpp
@@ -0,0 +1,83 @@
+#include <mbgl/util/run_loop.hpp>
+
+#include <uv.h>
+
+namespace mbgl {
+namespace util {
+
+uv::tls<RunLoop> RunLoop::current;
+
+class RunLoop::Impl {
+public:
+ Impl() = default;
+
+ uv_loop_t *loop;
+ RunLoop::Type type;
+};
+
+RunLoop::RunLoop(Type type) : impl(std::make_unique<Impl>()) {
+ switch (type) {
+ case Type::New:
+#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
+ impl->loop = uv_loop_new();
+ if (impl->loop == nullptr) {
+#else
+ impl->loop = new uv_loop_t;
+ if (uv_loop_init(impl->loop) != 0) {
+#endif
+ throw std::runtime_error("Failed to initialize loop.");
+ }
+ break;
+ case Type::Default:
+ impl->loop = uv_default_loop();
+ break;
+ }
+
+ impl->type = type;
+
+ current.set(this);
+ async = std::make_unique<AsyncTask>(std::bind(&RunLoop::process, this));
+}
+
+RunLoop::~RunLoop() {
+ current.set(nullptr);
+
+ if (impl->type == Type::Default) {
+ return;
+ }
+
+ // Run the loop again to ensure that async
+ // close callbacks have been called. Not needed
+ // for the default main loop because it is only
+ // closed when the application exits.
+ async.reset();
+ runOnce();
+
+#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
+ uv_loop_delete(impl->loop);
+#else
+ if (uv_loop_close(impl->loop) == UV_EBUSY) {
+ throw std::runtime_error("Failed to close loop.");
+ }
+ delete impl->loop;
+#endif
+}
+
+LOOP_HANDLE RunLoop::getLoopHandle() {
+ return current.get()->impl->loop;
+}
+
+void RunLoop::run() {
+ uv_run(impl->loop, UV_RUN_DEFAULT);
+}
+
+void RunLoop::runOnce() {
+ uv_run(impl->loop, UV_RUN_ONCE);
+}
+
+void RunLoop::stop() {
+ invoke([&] { async->unref(); });
+}
+
+}
+}
diff --git a/platform/node/src/node_mapbox_gl_native.cpp b/platform/node/src/node_mapbox_gl_native.cpp
index 4a86a8d855..e0b094d570 100644
--- a/platform/node/src/node_mapbox_gl_native.cpp
+++ b/platform/node/src/node_mapbox_gl_native.cpp
@@ -13,7 +13,7 @@
namespace node_mbgl {
mbgl::util::RunLoop& NodeRunLoop() {
- static mbgl::util::RunLoop nodeRunLoop(uv_default_loop());
+ static mbgl::util::RunLoop nodeRunLoop;
return nodeRunLoop;
}