Chromium Code Reviews| Index: Source/web/WebPluginContainerImpl.cpp |
| diff --git a/Source/web/WebPluginContainerImpl.cpp b/Source/web/WebPluginContainerImpl.cpp |
| index d93a9df6457773ad727018c1bf59805a0f89fc63..1e4ec4ac3355cc6a1d50c3f89df9554618da3c54 100644 |
| --- a/Source/web/WebPluginContainerImpl.cpp |
| +++ b/Source/web/WebPluginContainerImpl.cpp |
| @@ -175,7 +175,7 @@ void WebPluginContainerImpl::handleEvent(Event* event) |
| if (!m_webPlugin->acceptsInputEvents()) |
| return; |
| - RefPtr<WebPluginContainerImpl> protector(this); |
| + RefPtrWillBeRawPtr<WebPluginContainerImpl> protector(this); |
| // The events we pass are defined at: |
| // http://devedge-temp.mozilla.org/library/manuals/2002/plugin/1.0/structures5.html#1000000 |
| // Don't take the documentation as truth, however. There are many cases |
| @@ -439,7 +439,7 @@ v8::Local<v8::Object> WebPluginContainerImpl::v8ObjectForElement() |
| if (!scriptState->contextIsValid()) |
| return v8::Local<v8::Object>(); |
| - v8::Handle<v8::Value> v8value = toV8(m_element, scriptState->context()->Global(), scriptState->isolate()); |
| + v8::Handle<v8::Value> v8value = toV8(m_element.get(), scriptState->context()->Global(), scriptState->isolate()); |
| ASSERT(v8value->IsObject()); |
| return v8::Handle<v8::Object>::Cast(v8value); |
| @@ -674,56 +674,72 @@ bool WebPluginContainerImpl::paintCustomOverhangArea(GraphicsContext* context, c |
| // Private methods ------------------------------------------------------------- |
| WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement* element, WebPlugin* webPlugin) |
| -#if ENABLE(OILPAN) |
| - : m_frame(element->document().frame()) |
| -#else |
| : FrameDestructionObserver(element->document().frame()) |
| -#endif |
| , m_element(element) |
| , m_webPlugin(webPlugin) |
| - , m_webLayer(0) |
| + , m_webLayer(nullptr) |
| , m_touchEventRequestType(TouchEventRequestTypeNone) |
| , m_wantsWheelEvents(false) |
| +#if ENABLE(OILPAN) |
| + , m_isAllowedToDisposePlugin(false) |
| +#endif |
| { |
| } |
| WebPluginContainerImpl::~WebPluginContainerImpl() |
| { |
| #if ENABLE(OILPAN) |
| - // The element (and its document) are heap allocated and may |
| - // have been finalized by now; unsafe to unregister the touch |
| - // event handler at this stage. |
| - // |
| - // This is acceptable, as the widget will unregister itself if it |
| - // is cleanly detached. If an explicit detach doesn't happen, this |
| - // container is assumed to have died with the plugin element (and |
| - // its document), hence no unregistration step is needed. |
| - // |
| - m_element = 0; |
| + // The plugin container must have been disposed of already. |
| + if (m_isAllowedToDisposePlugin) |
| + dispose(); |
| + ASSERT(!m_webPlugin); |
| #else |
| - if (m_touchEventRequestType != TouchEventRequestTypeNone && m_element->document().frameHost()) |
| - m_element->document().frameHost()->eventHandlerRegistry().didRemoveEventHandler(*m_element, EventHandlerRegistry::TouchEvent); |
| + dispose(); |
| #endif |
| +} |
| + |
| +void WebPluginContainerImpl::dispose() |
| +{ |
| + if (m_element && m_touchEventRequestType != TouchEventRequestTypeNone && m_element->document().frameHost()) |
| + m_element->document().frameHost()->eventHandlerRegistry().didRemoveEventHandler(*m_element, EventHandlerRegistry::TouchEvent); |
| ScriptForbiddenScope::AllowSuperUnsafeScript thisShouldBeRemoved; |
| for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i) |
| m_pluginLoadObservers[i]->clearPluginContainer(); |
| m_webPlugin->destroy(); |
| + m_webPlugin = nullptr; |
| + |
| if (m_webLayer) |
| GraphicsLayer::unregisterContentsLayer(m_webLayer); |
| + |
| + m_pluginLoadObservers.clear(); |
| + m_scrollbarGroup.clear(); |
| + m_element = nullptr; |
| } |
| #if ENABLE(OILPAN) |
| -void WebPluginContainerImpl::detach() |
| -{ |
| - if (m_touchEventRequestType != TouchEventRequestTypeNone && m_element->document().frameHost()) |
| - m_element->document().frameHost()->eventHandlerRegistry().didRemoveEventHandler(*m_element, EventHandlerRegistry::TouchEvent); |
| - |
| - setWebLayer(0); |
| +void WebPluginContainerImpl::setIsAllowedToDisposePlugin() |
| +{ |
| + // If the LocalFrame is still alive, but the plugin element isn't, the |
| + // LocalFrame will set m_isAllowedToDisposePlugin via |
| + // its weak pointer callback. This is a signal that the plugin container |
| + // must dispose of its plugin when finalizing. The LocalFrame and |
| + // all objects accessible from it can safely be accessed, but not |
| + // the plugin element itself. |
|
haraken
2014/10/10 02:50:32
Help me understand:
1) Why can't you simply call
sof
2014/10/10 05:22:19
Unbounded amounts of work and allocation might res
|
| + ASSERT(!m_isAllowedToDisposePlugin); |
| + m_isAllowedToDisposePlugin = true; |
| + m_element = nullptr; |
| } |
| #endif |
| +void WebPluginContainerImpl::trace(Visitor* visitor) |
| +{ |
| + visitor->trace(m_element); |
| + FrameDestructionObserver::trace(visitor); |
| + PluginView::trace(visitor); |
| +} |
| + |
| void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) |
| { |
| ASSERT(parent()->isFrameView()); |