From 1f67471be3f93f97ae3fc5fba72435d80b49c445 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 13 Nov 2015 18:17:50 -0800 Subject: [PATCH] [node] Need to have a singleton RunLoop instance --- platform/node/src/node_file_source.cpp | 12 +++--------- platform/node/src/node_file_source.hpp | 2 -- platform/node/src/node_mapbox_gl_native.cpp | 15 +++++++++++++++ platform/node/src/node_mapbox_gl_native.hpp | 9 +++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 platform/node/src/node_mapbox_gl_native.hpp diff --git a/platform/node/src/node_file_source.cpp b/platform/node/src/node_file_source.cpp index 9a1d7c055af..5d7973f851e 100644 --- a/platform/node/src/node_file_source.cpp +++ b/platform/node/src/node_file_source.cpp @@ -1,5 +1,6 @@ #include "node_file_source.hpp" #include "node_request.hpp" +#include "node_mapbox_gl_native.hpp" namespace node_mbgl { @@ -8,15 +9,8 @@ class NodeFileSourceRequest : public mbgl::FileRequest { std::unique_ptr workRequest; }; -NodeFileSource::NodeFileSource(v8::Local options_) - : nodeLoop(uv_default_loop()) { +NodeFileSource::NodeFileSource(v8::Local options_) { options.Reset(options_); - - // This has the effect of unreffing an async handle, which otherwise would keep the - // default loop running. You would think we could do this in the destructor instead, - // but in fact the destructor might not get called if there's no GC pressure which - // would cause the NodeMap object which owns us to get destroyed. - nodeLoop.stop(); } NodeFileSource::~NodeFileSource() { @@ -28,7 +22,7 @@ std::unique_ptr NodeFileSource::request(const mbgl::Resource& // This function can be called from any thread. Make sure we're executing the // JS implementation in the node event loop. - req->workRequest = nodeLoop.invokeWithCallback([this] (mbgl::Resource res, Callback cb) { + req->workRequest = NodeRunLoop().invokeWithCallback([this] (mbgl::Resource res, Callback cb) { Nan::HandleScope scope; auto requestHandle = NodeRequest::Create(res, cb)->ToObject(); diff --git a/platform/node/src/node_file_source.hpp b/platform/node/src/node_file_source.hpp index 4234b791ae5..2ce673fb50a 100644 --- a/platform/node/src/node_file_source.hpp +++ b/platform/node/src/node_file_source.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -21,7 +20,6 @@ class NodeFileSource : public mbgl::FileSource { private: Nan::Persistent options; - mbgl::util::RunLoop nodeLoop; }; } diff --git a/platform/node/src/node_mapbox_gl_native.cpp b/platform/node/src/node_mapbox_gl_native.cpp index 5bf03594e5a..76c522d83e4 100644 --- a/platform/node/src/node_mapbox_gl_native.cpp +++ b/platform/node/src/node_mapbox_gl_native.cpp @@ -6,11 +6,26 @@ #include #pragma GCC diagnostic pop +#include "node_mapbox_gl_native.hpp" #include "node_map.hpp" #include "node_log.hpp" #include "node_request.hpp" +namespace node_mbgl { + +mbgl::util::RunLoop& NodeRunLoop() { + static mbgl::util::RunLoop nodeRunLoop(uv_default_loop()); + return nodeRunLoop; +} + +} + 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 new file mode 100644 index 00000000000..b98b035fea8 --- /dev/null +++ b/platform/node/src/node_mapbox_gl_native.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace node_mbgl { + +mbgl::util::RunLoop& NodeRunLoop(); + +}