summaryrefslogtreecommitdiff
path: root/platform/default/run_loop.cpp
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/default/run_loop.cpp
parent1d623322044c4650bb39c9224f596341a23f490f (diff)
downloadqtlocation-mapboxgl-d422c8cac4e436fb2fb1eeafbae5ed5d847e0b00.tar.gz
[core] Abstract main loop inside RunLoop class
Diffstat (limited to 'platform/default/run_loop.cpp')
-rw-r--r--platform/default/run_loop.cpp83
1 files changed, 83 insertions, 0 deletions
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(); });
+}
+
+}
+}