summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/default/async_task.cpp1
-rw-r--r--platform/default/run_loop.cpp29
-rw-r--r--platform/default/timer.cpp1
3 files changed, 30 insertions, 1 deletions
diff --git a/platform/default/async_task.cpp b/platform/default/async_task.cpp
index 00fe9ac5f0..05cf759863 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 b259fdfd21..76c01b80b7 100644
--- a/platform/default/run_loop.cpp
+++ b/platform/default/run_loop.cpp
@@ -13,6 +13,12 @@ namespace {
using namespace mbgl::util;
static ThreadLocal<RunLoop>& current = *new ThreadLocal<RunLoop>;
+#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<uv_async_t*>(h);
+ });
+ }
+
+ uv_handle_t* holderHandle() {
+ return reinterpret_cast<uv_handle_t*>(holder);
+ }
+
uv_loop_t *loop = nullptr;
+ uv_async_t* holder = new uv_async_t;
RunLoop::Type type;
std::unique_ptr<AsyncTask> async;
@@ -82,6 +99,12 @@ RunLoop::RunLoop(Type type) : impl(std::make_unique<Impl>()) {
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<Impl>()) {
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<void(int, Event)>&& callback) {
diff --git a/platform/default/timer.cpp b/platform/default/timer.cpp
index 5d7d0757e9..473f059133 100644
--- a/platform/default/timer.cpp
+++ b/platform/default/timer.cpp
@@ -22,6 +22,7 @@ public:
}
handle()->data = this;
+ uv_unref(handle());
}
~Impl() {