Index: third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp |
index a8c1c700380a0fd7413c5298a9c25f9b923ce0f2..524680efb52f1c501fc519072797b339a1023c76 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp |
@@ -48,19 +48,17 @@ V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, DOMWrapperWor |
, m_isAttribute(isAttribute) |
, m_world(world) |
, m_isolate(isolate) |
+ , m_workerGlobalScope(nullptr) |
{ |
if (isMainThread()) |
InstanceCounters::incrementCounter(InstanceCounters::JSEventListenerCounter); |
+ else |
+ m_workerGlobalScope = toWorkerGlobalScope(currentExecutionContext(isolate)); |
} |
V8AbstractEventListener::~V8AbstractEventListener() |
{ |
- if (!m_listener.isEmpty()) { |
- v8::HandleScope scope(isolate()); |
- // We can't use a ScriptState::Scope here as the per-context data might already be gone at this point. |
- v8::Context::Scope contextScope(m_scriptStateForListener->context()); |
- V8EventListenerList::clearWrapper(m_listener.newLocal(isolate()), m_isAttribute, m_scriptStateForListener.get()); |
- } |
+ ASSERT(m_listener.isEmpty()); |
if (isMainThread()) |
InstanceCounters::decrementCounter(InstanceCounters::JSEventListenerCounter); |
} |
@@ -102,11 +100,21 @@ void V8AbstractEventListener::handleEvent(ScriptState* scriptState, Event* event |
invokeEventHandler(scriptState, event, v8::Local<v8::Value>::New(isolate(), jsEvent)); |
} |
-void V8AbstractEventListener::setListenerObject(v8::Local<v8::Object> listener, ScriptState* scriptState) |
+void V8AbstractEventListener::setListenerObject(v8::Local<v8::Object> listener) |
{ |
+ ASSERT(m_listener.isEmpty()); |
+ // Balanced in secondWeakCallback xor clearListenerObject. |
+ if (m_workerGlobalScope) { |
+ m_workerGlobalScope->registerEventListener(this); |
+ } else { |
+#if ENABLE(OILPAN) |
+ m_keepAlive = this; |
+#else |
+ ref(); |
+#endif |
+ } |
m_listener.set(isolate(), listener); |
m_listener.setWeak(this, &setWeakCallback); |
- m_scriptStateForListener = scriptState; |
} |
void V8AbstractEventListener::invokeEventHandler(ScriptState* scriptState, Event* event, v8::Local<v8::Value> jsEvent) |
@@ -184,10 +192,47 @@ bool V8AbstractEventListener::belongsToTheCurrentWorld() const |
return ScriptState::hasCurrentScriptState(isolate()) && &world() == &DOMWrapperWorld::current(isolate()); |
} |
-void V8AbstractEventListener::setWeakCallback(const v8::WeakCallbackInfo<V8AbstractEventListener> &data) |
+void V8AbstractEventListener::clearListenerObject() |
+{ |
+ if (!hasExistingListenerObject()) |
+ return; |
+ m_listener.clear(); |
+ if (m_workerGlobalScope) { |
+ m_workerGlobalScope->deregisterEventListener(this); |
+ } else { |
+#if ENABLE(OILPAN) |
+ m_keepAlive.clear(); |
+#else |
+ deref(); |
+#endif |
+ } |
+} |
+ |
+void V8AbstractEventListener::setWeakCallback(const v8::WeakCallbackInfo<V8AbstractEventListener>& data) |
{ |
data.GetParameter()->m_listener.clear(); |
- data.GetParameter()->m_scriptStateForListener.clear(); |
+ data.SetSecondPassCallback(secondWeakCallback); |
+} |
+ |
+void V8AbstractEventListener::secondWeakCallback(const v8::WeakCallbackInfo<V8AbstractEventListener>& data) |
+{ |
+ if (data.GetParameter()->m_workerGlobalScope) { |
+ data.GetParameter()->m_workerGlobalScope->deregisterEventListener(data.GetParameter()); |
+ } else { |
+#if ENABLE(OILPAN) |
+ data.GetParameter()->m_keepAlive.clear(); |
+#else |
+ data.GetParameter()->deref(); |
+#endif |
+ } |
+} |
+ |
+DEFINE_TRACE(V8AbstractEventListener) |
+{ |
+#if ENABLE(OILPAN) |
+ visitor->trace(m_workerGlobalScope); |
+#endif |
+ EventListener::trace(visitor); |
} |
} // namespace blink |