#include #include namespace mbgl { namespace util { uv::tls RunLoop::current; class RunLoop::Impl { public: Impl() = default; uv_loop_t *loop; RunLoop::Type type; }; RunLoop::RunLoop(Type type) : impl(std::make_unique()) { 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(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(); }); } } }