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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user