Fix finding the WebContents of a pending renderer process
Apparently after Chrome 44 a renderer process can be started before the corresponding render view is created, though it can be patched but from the source code Chromium is enforcing this everywhere now, so fixing it on our side seems the only reliable solution. This fix is very similar to what we did, but instead of blindly setting swapped process, we now remember which process the pending process is going to replace, so we should not have those race conditions.
This commit is contained in:
parent
0f990d40cc
commit
e6a2b0a479
2 changed files with 39 additions and 12 deletions
|
@ -20,6 +20,7 @@
|
|||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
|
@ -62,20 +63,14 @@ enum ProcessOwner {
|
|||
ProcessOwner GetProcessOwner(int process_id,
|
||||
NativeWindow** window,
|
||||
WebViewManager::WebViewInfo* info) {
|
||||
content::RenderViewHost* rvh = content::RenderViewHost::FromID(
|
||||
process_id, kDefaultRoutingID);
|
||||
if (!rvh)
|
||||
return OWNER_NONE;
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(rvh);
|
||||
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||
if (!web_contents)
|
||||
return OWNER_NONE;
|
||||
|
||||
// First search for NativeWindow.
|
||||
for (auto native_window : *WindowList::GetInstance())
|
||||
if (web_contents == native_window->web_contents()) {
|
||||
*window = native_window;
|
||||
return OWNER_NATIVE_WINDOW;
|
||||
}
|
||||
if ((*window = NativeWindow::FromWebContents(web_contents)))
|
||||
return OWNER_NATIVE_WINDOW;
|
||||
|
||||
// Then search for guest WebContents.
|
||||
if (WebViewManager::GetInfoForWebContents(web_contents, info))
|
||||
|
@ -189,6 +184,13 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
|||
return;
|
||||
|
||||
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
|
||||
|
||||
// Remember the original renderer process of the pending renderer process.
|
||||
auto current_process = current_instance->GetProcess();
|
||||
auto pending_process = (*new_instance)->GetProcess();
|
||||
pending_processes_[pending_process->GetID()] = current_process->GetID();
|
||||
// Clear the entry in map when process ends.
|
||||
current_process->AddObserver(this);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
|
@ -212,6 +214,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
|||
}
|
||||
#endif
|
||||
|
||||
// If the process is a pending process, we should use the old one.
|
||||
if (ContainsKey(pending_processes_, process_id))
|
||||
process_id = pending_processes_[process_id];
|
||||
|
||||
NativeWindow* window;
|
||||
WebViewManager::WebViewInfo info;
|
||||
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
|
||||
|
@ -268,4 +274,15 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
|||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessHostDestroyed(
|
||||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
for (const auto& entry : pending_processes_) {
|
||||
if (entry.first == process_id || entry.second == process_id) {
|
||||
pending_processes_.erase(entry.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
#ifndef ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "content/public/browser/render_process_host_observer.h"
|
||||
|
||||
namespace content {
|
||||
class QuotaPermissionContext;
|
||||
|
@ -21,7 +23,8 @@ class SSLCertRequestInfo;
|
|||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserClient : public brightray::BrowserClient {
|
||||
class AtomBrowserClient : public brightray::BrowserClient,
|
||||
public content::RenderProcessHostObserver {
|
||||
public:
|
||||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
@ -54,10 +57,17 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
|||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
|
||||
private:
|
||||
// brightray::BrowserClient:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
private:
|
||||
// pending_render_process => current_render_process.
|
||||
std::map<int, int> pending_processes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue