When a pending contents is created but deleted before it is shown, remove it from the list of pending contents

This happens during running layout tests when all newly opened windows are
closed, however, an IPC message to show one of the new windows is already in
flight

The other direction, when the opener is deleted, is already covered by existing
code.

BUG=180969
[email protected]
TEST=content_unittests:WebContentsImplTest.PendingContents

Review URL: https://chromiumcodereview.appspot.com/12602003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186893 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 37e11c7..28d9ef25 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1225,7 +1225,20 @@
     registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
                       Source<WebContents>(opener_));
     opener_ = NULL;
+    return;
   }
+  // Clear a pending contents that has been closed before being shown.
+  for (PendingContents::iterator iter = pending_contents_.begin();
+       iter != pending_contents_.end();
+       ++iter) {
+    if (iter->second != web_contents)
+      continue;
+    pending_contents_.erase(iter);
+    registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
+                      Source<WebContents>(web_contents));
+    return;
+  }
+  NOTREACHED();
 }
 
 void WebContentsImpl::AddObserver(WebContentsObserver* observer) {
@@ -1407,6 +1420,8 @@
     // later.
     DCHECK_NE(MSG_ROUTING_NONE, route_id);
     pending_contents_[route_id] = new_contents;
+    registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
+                   Source<WebContents>(new_contents));
   }
 
   if (delegate_) {
@@ -1540,6 +1555,8 @@
 
   WebContentsImpl* new_contents = iter->second;
   pending_contents_.erase(route_id);
+  registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
+                    Source<WebContents>(new_contents));
 
   if (!new_contents->GetRenderProcessHost()->HasConnection() ||
       !new_contents->GetRenderViewHost()->GetView())
@@ -2982,6 +2999,8 @@
 void WebContentsImpl::DidDisownOpener(RenderViewHost* rvh) {
   // Clear our opener so that future cross-process navigations don't have an
   // opener assigned.
+  registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
+                    Source<WebContents>(opener_));
   opener_ = NULL;
 
   // Notify all swapped out RenderViewHosts for this tab.  This is important