diff options
Diffstat (limited to 'platform/default/run_loop.cpp')
-rw-r--r-- | platform/default/run_loop.cpp | 83 |
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(); }); +} + +} +} |