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 "atom/common/options_switches.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
|
#include "base/stl_util.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "chrome/browser/printing/printing_message_filter.h"
|
#include "chrome/browser/printing/printing_message_filter.h"
|
||||||
|
@ -62,20 +63,14 @@ enum ProcessOwner {
|
||||||
ProcessOwner GetProcessOwner(int process_id,
|
ProcessOwner GetProcessOwner(int process_id,
|
||||||
NativeWindow** window,
|
NativeWindow** window,
|
||||||
WebViewManager::WebViewInfo* info) {
|
WebViewManager::WebViewInfo* info) {
|
||||||
content::RenderViewHost* rvh = content::RenderViewHost::FromID(
|
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
|
||||||
process_id, kDefaultRoutingID);
|
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||||
if (!rvh)
|
|
||||||
return OWNER_NONE;
|
|
||||||
auto web_contents = content::WebContents::FromRenderViewHost(rvh);
|
|
||||||
if (!web_contents)
|
if (!web_contents)
|
||||||
return OWNER_NONE;
|
return OWNER_NONE;
|
||||||
|
|
||||||
// First search for NativeWindow.
|
// First search for NativeWindow.
|
||||||
for (auto native_window : *WindowList::GetInstance())
|
if ((*window = NativeWindow::FromWebContents(web_contents)))
|
||||||
if (web_contents == native_window->web_contents()) {
|
return OWNER_NATIVE_WINDOW;
|
||||||
*window = native_window;
|
|
||||||
return OWNER_NATIVE_WINDOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then search for guest WebContents.
|
// Then search for guest WebContents.
|
||||||
if (WebViewManager::GetInfoForWebContents(web_contents, info))
|
if (WebViewManager::GetInfoForWebContents(web_contents, info))
|
||||||
|
@ -189,6 +184,13 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
|
*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(
|
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
|
@ -212,6 +214,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
NativeWindow* window;
|
||||||
WebViewManager::WebViewInfo info;
|
WebViewManager::WebViewInfo info;
|
||||||
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
|
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
|
||||||
|
@ -268,4 +274,15 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||||
return new AtomBrowserMainParts;
|
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
|
} // namespace atom
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
#ifndef ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
#ifndef ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||||
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "brightray/browser/browser_client.h"
|
#include "brightray/browser/browser_client.h"
|
||||||
|
#include "content/public/browser/render_process_host_observer.h"
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class QuotaPermissionContext;
|
class QuotaPermissionContext;
|
||||||
|
@ -21,7 +23,8 @@ class SSLCertRequestInfo;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class AtomBrowserClient : public brightray::BrowserClient {
|
class AtomBrowserClient : public brightray::BrowserClient,
|
||||||
|
public content::RenderProcessHostObserver {
|
||||||
public:
|
public:
|
||||||
AtomBrowserClient();
|
AtomBrowserClient();
|
||||||
virtual ~AtomBrowserClient();
|
virtual ~AtomBrowserClient();
|
||||||
|
@ -54,10 +57,17 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||||
net::SSLCertRequestInfo* cert_request_info,
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||||
|
|
||||||
private:
|
// brightray::BrowserClient:
|
||||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||||
const content::MainFunctionParams&) override;
|
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);
|
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue