Make Wrappable thread safe

This commit is contained in:
Cheng Zhao 2017-03-08 16:33:05 +09:00
parent ad0fd82566
commit ed909cd54c

View file

@ -6,6 +6,8 @@
#define NATIVE_MATE_WRAPPABLE_H_ #define NATIVE_MATE_WRAPPABLE_H_
#include "base/bind.h" #include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "native_mate/compat.h" #include "native_mate/compat.h"
#include "native_mate/converter.h" #include "native_mate/converter.h"
#include "native_mate/constructor.h" #include "native_mate/constructor.h"
@ -30,18 +32,18 @@ class Wrappable : public WrappableBase {
isolate, base::Bind(&internal::InvokeNew<Sig>, constructor)); isolate, base::Bind(&internal::InvokeNew<Sig>, constructor));
templ->InstanceTemplate()->SetInternalFieldCount(1); templ->InstanceTemplate()->SetInternalFieldCount(1);
T::BuildPrototype(isolate, templ); T::BuildPrototype(isolate, templ);
templ_ = new v8::Global<v8::FunctionTemplate>(isolate, templ); templ_.Get().Set(new v8::Global<v8::FunctionTemplate>(isolate, templ));
} }
static v8::Local<v8::FunctionTemplate> GetConstructor(v8::Isolate* isolate) { static v8::Local<v8::FunctionTemplate> GetConstructor(v8::Isolate* isolate) {
// Fill the object template. // Fill the object template.
if (!templ_) { if (!templ_.Get().Get()) {
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->InstanceTemplate()->SetInternalFieldCount(1); templ->InstanceTemplate()->SetInternalFieldCount(1);
T::BuildPrototype(isolate, templ); T::BuildPrototype(isolate, templ);
templ_ = new v8::Global<v8::FunctionTemplate>(isolate, templ); templ_.Get().Set(new v8::Global<v8::FunctionTemplate>(isolate, templ));
} }
return v8::Local<v8::FunctionTemplate>::New(isolate, *templ_); return v8::Local<v8::FunctionTemplate>::New(isolate, *templ_.Get().Get());
} }
protected: protected:
@ -63,14 +65,16 @@ class Wrappable : public WrappableBase {
} }
private: private:
static v8::Global<v8::FunctionTemplate>* templ_; // Leaked on purpose static base::LazyInstance<base::ThreadLocalPointer<
v8::Global<v8::FunctionTemplate>>> templ_;
DISALLOW_COPY_AND_ASSIGN(Wrappable); DISALLOW_COPY_AND_ASSIGN(Wrappable);
}; };
// static // static
template<typename T> template<typename T>
v8::Global<v8::FunctionTemplate>* Wrappable<T>::templ_ = nullptr; base::LazyInstance<base::ThreadLocalPointer<v8::Global<v8::FunctionTemplate>>>
Wrappable<T>::templ_ = LAZY_INSTANCE_INITIALIZER;
// This converter handles any subclass of Wrappable. // This converter handles any subclass of Wrappable.
template <typename T> template <typename T>