Fix invalid NodeRequest reference

On the code path built with node v0.12.4, we are storing
an invalid reference to NodeRequest on the "pending" list. It will
crash when we need to access it like we do when canceling a request.

Ideally we should just have a "std::unordered_map<mbgl::Resource,
v8::UniquePersistent>" but that is not possible because the move
semantics are not fully implemented until V8 v4.3.22. It can be used
on a std::vector but not on a std::map.

See: https://code.google.com/p/v8/issues/detail?id=3669

The solution for keep using C++11 move semantics is to declare the
v8::CopyablePersistentTraits shenanigans and explicitly clear the
v8::Persistent (like we do already for node v0.10).

When Node gets V8 v4.3.22+ we can go back to v8::UniquePersistent
with a more clear implementation.
This commit is contained in:
Thiago Marcos P. Santos
2015-06-15 01:55:20 +03:00
parent 34ef7ac003
commit b602835626
2 changed files with 6 additions and 10 deletions

View File

@@ -121,12 +121,9 @@ void NodeFileSource::processAdd(const mbgl::Resource& resource) {
auto handle = NanObjectWrapHandle(this);
auto requestHandle = NanNew<v8::Object>(NodeRequest::Create(handle, resource));
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
const v8::UniquePersistent<v8::Object> requestPersistent(v8::Isolate::GetCurrent(), requestHandle);
#else
v8::Persistent<v8::Object> requestPersistent;
NanAssignPersistent(requestPersistent, requestHandle);
#endif
pending.emplace(resource, std::move(requestPersistent));
v8::Local<v8::Value> argv[] = { requestHandle };
@@ -143,12 +140,9 @@ void NodeFileSource::processCancel(const mbgl::Resource& resource) {
} else {
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
auto requestHandle = v8::Local<v8::Object>::New(v8::Isolate::GetCurrent(), it->second);
it->second.Reset();
#else
auto requestHandle = NanNew<v8::Object>(it->second);
#endif
// Dispose and remove the persistent handle
#if (NODE_MODULE_VERSION <= NODE_0_10_MODULE_VERSION)
NanDisposePersistent(it->second);
#endif
pending.erase(it);
@@ -173,7 +167,9 @@ void NodeFileSource::notify(const mbgl::Resource& resource, const std::shared_pt
// First, remove the request, since it might be destructed at any point now.
auto it = pending.find(resource);
if (it != pending.end()) {
#if (NODE_MODULE_VERSION <= NODE_0_10_MODULE_VERSION)
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
it->second.Reset();
#else
NanDisposePersistent(it->second);
#endif
pending.erase(it);

View File

@@ -49,7 +49,7 @@ private:
private:
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
std::unordered_map<mbgl::Resource, const v8::UniquePersistent<v8::Object> &, mbgl::Resource::Hash> pending;
std::unordered_map<mbgl::Resource, v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>, mbgl::Resource::Hash> pending;
#else
std::unordered_map<mbgl::Resource, v8::Persistent<v8::Object>, mbgl::Resource::Hash> pending;
#endif