Index: chrome/browser/guest_view/guest_view_base.cc |
diff --git a/chrome/browser/guest_view/guest_view_base.cc b/chrome/browser/guest_view/guest_view_base.cc |
index 2b335016103e3249da6db11bd06b7678623008e5..e08be88c8611d64889d06c91ab7717c9c51c8757 100644 |
--- a/chrome/browser/guest_view/guest_view_base.cc |
+++ b/chrome/browser/guest_view/guest_view_base.cc |
@@ -50,6 +50,7 @@ class GuestViewBase::EmbedderWebContentsObserver : public WebContentsObserver { |
public: |
explicit EmbedderWebContentsObserver(GuestViewBase* guest) |
: WebContentsObserver(guest->embedder_web_contents()), |
+ destroyed_(false), |
guest_(guest) { |
} |
@@ -58,14 +59,26 @@ class GuestViewBase::EmbedderWebContentsObserver : public WebContentsObserver { |
// WebContentsObserver implementation. |
virtual void WebContentsDestroyed() OVERRIDE { |
- guest_->embedder_web_contents_ = NULL; |
- guest_->EmbedderDestroyed(); |
- guest_->Destroy(); |
+ Destroy(); |
+ } |
+ |
+ virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE { |
+ Destroy(); |
} |
private: |
+ bool destroyed_; |
GuestViewBase* guest_; |
+ void Destroy() { |
+ if (destroyed_) |
+ return; |
+ destroyed_ = true; |
+ guest_->embedder_web_contents_ = NULL; |
+ guest_->EmbedderDestroyed(); |
+ guest_->Destroy(); |
+ } |
+ |
DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver); |
}; |
@@ -92,7 +105,7 @@ void GuestViewBase::Init( |
CreateWebContents(embedder_extension_id, |
embedder_render_process_id, |
create_params, |
- base::Bind(&GuestViewBase::CompleteCreateWebContents, |
+ base::Bind(&GuestViewBase::CompleteInit, |
AsWeakPtr(), |
embedder_extension_id, |
embedder_render_process_id, |
@@ -214,6 +227,7 @@ void GuestViewBase::RenderProcessExited(content::RenderProcessHost* host, |
} |
void GuestViewBase::Destroy() { |
+ DCHECK(guest_web_contents()); |
content::RenderProcessHost* host = |
content::RenderProcessHost::FromID(embedder_render_process_id()); |
if (host) |
@@ -221,6 +235,12 @@ void GuestViewBase::Destroy() { |
WillDestroy(); |
if (!destruction_callback_.is_null()) |
destruction_callback_.Run(); |
+ |
+ webcontents_guestview_map.Get().erase(guest_web_contents()); |
+ GuestViewManager::FromBrowserContext(browser_context_)-> |
+ RemoveGuest(guest_instance_id_); |
+ pending_events_.clear(); |
+ |
delete guest_web_contents(); |
} |
@@ -292,14 +312,6 @@ bool GuestViewBase::PreHandleGestureEvent(content::WebContents* source, |
} |
GuestViewBase::~GuestViewBase() { |
- std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_); |
- |
- webcontents_guestview_map.Get().erase(guest_web_contents()); |
- |
- GuestViewManager::FromBrowserContext(browser_context_)-> |
- RemoveGuest(guest_instance_id_); |
- |
- pending_events_.clear(); |
} |
void GuestViewBase::DispatchEvent(Event* event) { |
@@ -341,12 +353,14 @@ void GuestViewBase::SendQueuedEvents() { |
} |
} |
-void GuestViewBase::CompleteCreateWebContents( |
- const std::string& embedder_extension_id, |
- int embedder_render_process_id, |
- const WebContentsCreatedCallback& callback, |
- content::WebContents* guest_web_contents) { |
+void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, |
+ int embedder_render_process_id, |
+ const WebContentsCreatedCallback& callback, |
+ content::WebContents* guest_web_contents) { |
if (!guest_web_contents) { |
+ // The derived class did not create a WebContents so this class serves no |
+ // purpose. Let's self-destruct. |
+ delete this; |
lazyboy
2014/07/07 21:34:44
Can you call callback.Run(this) after "delete this
Fady Samuel
2014/07/08 15:47:08
Yes, this callback is a local variable. We can't a
|
callback.Run(NULL); |
return; |
} |