From 3633fd7ebdb2f406f17cf05320f9480a73455e09 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 20 Feb 2016 13:31:12 +0200 Subject: [PATCH] [node] Destroy the RunLoop with the last Map object The last map object to get destroyed will also destroy the RunLoop (which will also destroy the AsyncTask). This will clear any reference to the Node default main loop and let it close. Downside is that we need to make sure we are always calling `map.release()`. --- platform/node/src/node_map.cpp | 4 +++- platform/node/src/node_map.hpp | 2 ++ platform/node/src/node_mapbox_gl_native.cpp | 18 ++++++++++-------- platform/node/src/node_mapbox_gl_native.hpp | 4 +++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 5eefe402d..afd3ae84f 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -439,6 +439,7 @@ void NodeMap::release() { }); map.reset(nullptr); + loop.reset(); } NAN_METHOD(NodeMap::DumpDebugLogs) { @@ -458,6 +459,7 @@ NodeMap::NodeMap(v8::Local options) : Nan::HandleScope scope; return Nan::Has(options, Nan::New("ratio").ToLocalChecked()).FromJust() ? Nan::Get(options, Nan::New("ratio").ToLocalChecked()).ToLocalChecked()->NumberValue() : 1.0; }()), + loop(NodeRunLoop()), map(std::make_unique(view, *this, mbgl::MapMode::Still)), async(new uv_async_t) { @@ -484,7 +486,7 @@ std::unique_ptr NodeMap::request(const mbgl::Resource& resour // This function can be called from any thread. Make sure we're executing the // JS implementation in the node event loop. - req->workRequest = NodeRunLoop().invokeWithCallback([this] (mbgl::Resource res, Callback cb2) { + req->workRequest = loop->invokeWithCallback([this] (mbgl::Resource res, Callback cb2) { Nan::HandleScope scope; auto requestHandle = NodeRequest::Create(res, cb2)->ToObject(); diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index fe36ae7ed..42b312510 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -45,6 +46,7 @@ public: std::unique_ptr request(const mbgl::Resource&, Callback); mbgl::HeadlessView view; + std::shared_ptr loop; std::unique_ptr map; std::exception_ptr error; diff --git a/platform/node/src/node_mapbox_gl_native.cpp b/platform/node/src/node_mapbox_gl_native.cpp index e0b094d57..313f16f28 100644 --- a/platform/node/src/node_mapbox_gl_native.cpp +++ b/platform/node/src/node_mapbox_gl_native.cpp @@ -12,19 +12,21 @@ namespace node_mbgl { -mbgl::util::RunLoop& NodeRunLoop() { - static mbgl::util::RunLoop nodeRunLoop; - return nodeRunLoop; +std::shared_ptr NodeRunLoop() { + static std::weak_ptr nodeRunLoop; + + auto loop = nodeRunLoop.lock(); + if (!loop) { + loop = std::make_shared(); + nodeRunLoop = loop; + } + + return std::move(loop); } } NAN_MODULE_INIT(RegisterModule) { - // This has the effect of: - // a) Ensuring that the static local variable is initialized before any thread contention. - // b) unreffing an async handle, which otherwise would keep the default loop running. - node_mbgl::NodeRunLoop().stop(); - node_mbgl::NodeMap::Init(target); node_mbgl::NodeRequest::Init(target); diff --git a/platform/node/src/node_mapbox_gl_native.hpp b/platform/node/src/node_mapbox_gl_native.hpp index b98b035fe..0dcf8dcd0 100644 --- a/platform/node/src/node_mapbox_gl_native.hpp +++ b/platform/node/src/node_mapbox_gl_native.hpp @@ -2,8 +2,10 @@ #include +#include + namespace node_mbgl { -mbgl::util::RunLoop& NodeRunLoop(); +std::shared_ptr NodeRunLoop(); }