[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()`.
This commit is contained in:
Thiago Marcos P. Santos
2016-02-20 13:31:12 +02:00
parent 8a53c1a881
commit 3633fd7ebd
4 changed files with 18 additions and 10 deletions

View File

@@ -439,6 +439,7 @@ void NodeMap::release() {
});
map.reset(nullptr);
loop.reset();
}
NAN_METHOD(NodeMap::DumpDebugLogs) {
@@ -458,6 +459,7 @@ NodeMap::NodeMap(v8::Local<v8::Object> 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<mbgl::Map>(view, *this, mbgl::MapMode::Still)),
async(new uv_async_t) {
@@ -484,7 +486,7 @@ std::unique_ptr<mbgl::FileRequest> 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();

View File

@@ -3,6 +3,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/util/run_loop.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -45,6 +46,7 @@ public:
std::unique_ptr<mbgl::FileRequest> request(const mbgl::Resource&, Callback);
mbgl::HeadlessView view;
std::shared_ptr<mbgl::util::RunLoop> loop;
std::unique_ptr<mbgl::Map> map;
std::exception_ptr error;

View File

@@ -12,19 +12,21 @@
namespace node_mbgl {
mbgl::util::RunLoop& NodeRunLoop() {
static mbgl::util::RunLoop nodeRunLoop;
return nodeRunLoop;
std::shared_ptr<mbgl::util::RunLoop> NodeRunLoop() {
static std::weak_ptr<mbgl::util::RunLoop> nodeRunLoop;
auto loop = nodeRunLoop.lock();
if (!loop) {
loop = std::make_shared<mbgl::util::RunLoop>();
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);

View File

@@ -2,8 +2,10 @@
#include <mbgl/util/run_loop.hpp>
#include <memory>
namespace node_mbgl {
mbgl::util::RunLoop& NodeRunLoop();
std::shared_ptr<mbgl::util::RunLoop> NodeRunLoop();
}