From 931ac77af45c4bbcb5dbfdfb55b6711ad8892f69 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Tue, 23 Feb 2016 15:24:39 +0200 Subject: [PATCH] Revert "[core] libuv unref() not really needed" This reverts commit 8a53c1a881c6a5272b647ca267d40fbc435d11d9. --- platform/default/async_task.cpp | 1 + platform/default/run_loop.cpp | 29 ++++++++++++++++++++++++++++- platform/default/timer.cpp | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/platform/default/async_task.cpp b/platform/default/async_task.cpp index 00fe9ac5f..05cf75986 100644 --- a/platform/default/async_task.cpp +++ b/platform/default/async_task.cpp @@ -28,6 +28,7 @@ public: } handle()->data = this; + uv_unref(handle()); } ~Impl() { diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp index b259fdfd2..76c01b80b 100644 --- a/platform/default/run_loop.cpp +++ b/platform/default/run_loop.cpp @@ -13,6 +13,12 @@ namespace { using namespace mbgl::util; static ThreadLocal& current = *new ThreadLocal; +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 +void dummyCallback(uv_async_t*, int) {}; +#else +void dummyCallback(uv_async_t*) {}; +#endif + } // namespace namespace mbgl { @@ -56,7 +62,18 @@ RunLoop* RunLoop::Get() { class RunLoop::Impl { public: + void closeHolder() { + uv_close(holderHandle(), [](uv_handle_t* h) { + delete reinterpret_cast(h); + }); + } + + uv_handle_t* holderHandle() { + return reinterpret_cast(holder); + } + uv_loop_t *loop = nullptr; + uv_async_t* holder = new uv_async_t; RunLoop::Type type; std::unique_ptr async; @@ -82,6 +99,12 @@ RunLoop::RunLoop(Type type) : impl(std::make_unique()) { break; } + // Just for holding a ref to the main loop and keep + // it alive as required by libuv. + if (uv_async_init(impl->loop, impl->holder, dummyCallback) != 0) { + throw std::runtime_error("Failed to initialize async."); + } + impl->type = type; current.set(this); @@ -91,6 +114,10 @@ RunLoop::RunLoop(Type type) : impl(std::make_unique()) { RunLoop::~RunLoop() { current.set(nullptr); + // Close the dummy handle that we have + // just to keep the main loop alive. + impl->closeHolder(); + if (impl->type == Type::Default) { return; } @@ -134,7 +161,7 @@ void RunLoop::runOnce() { } void RunLoop::stop() { - invoke([&] { uv_stop(impl->loop); }); + invoke([&] { uv_unref(impl->holderHandle()); }); } void RunLoop::addWatch(int fd, Event event, std::function&& callback) { diff --git a/platform/default/timer.cpp b/platform/default/timer.cpp index 5d7d0757e..473f05913 100644 --- a/platform/default/timer.cpp +++ b/platform/default/timer.cpp @@ -22,6 +22,7 @@ public: } handle()->data = this; + uv_unref(handle()); } ~Impl() {