Remove the race condition between new process creation and context release (#12342)
* Remove the race condition between new process creation and old process releasing remote context Previously there was a race condition where the getId() method would return the new context ID even though the release was for the old context. This changes it to send the "initial" context ID with the release message to ensure there is no race. * fetch context ID from remote in sandbox mode
This commit is contained in:
parent
9599615b23
commit
0ac883c6d4
7 changed files with 31 additions and 6 deletions
|
@ -1033,13 +1033,17 @@ void WebContents::NavigationEntryCommitted(
|
||||||
details.is_same_document, details.did_replace_entry);
|
details.is_same_document, details.did_replace_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t WebContents::GetID() const {
|
int64_t WebContents::GetIDForContents(content::WebContents* web_contents) {
|
||||||
int64_t process_id = web_contents()->GetRenderProcessHost()->GetID();
|
int64_t process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||||
int64_t routing_id = web_contents()->GetRenderViewHost()->GetRoutingID();
|
int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID();
|
||||||
int64_t rv = (process_id << 32) + routing_id;
|
int64_t rv = (process_id << 32) + routing_id;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t WebContents::GetID() const {
|
||||||
|
return WebContents::GetIDForContents(web_contents());
|
||||||
|
}
|
||||||
|
|
||||||
int WebContents::GetProcessID() const {
|
int WebContents::GetProcessID() const {
|
||||||
return web_contents()->GetRenderProcessHost()->GetID();
|
return web_contents()->GetRenderProcessHost()->GetID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
static int64_t GetIDForContents(content::WebContents* web_contents);
|
||||||
|
|
||||||
// Notifies to destroy any guest web contents before destroying self.
|
// Notifies to destroy any guest web contents before destroying self.
|
||||||
void DestroyWebContents(bool async);
|
void DestroyWebContents(bool async);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_app.h"
|
#include "atom/browser/api/atom_api_app.h"
|
||||||
#include "atom/browser/api/atom_api_protocol.h"
|
#include "atom/browser/api/atom_api_protocol.h"
|
||||||
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/atom_quota_permission_context.h"
|
#include "atom/browser/atom_quota_permission_context.h"
|
||||||
|
@ -322,6 +323,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
web_contents, command_line);
|
web_contents, command_line);
|
||||||
SessionPreferences::AppendExtraCommandLineSwitches(
|
SessionPreferences::AppendExtraCommandLineSwitches(
|
||||||
web_contents->GetBrowserContext(), command_line);
|
web_contents->GetBrowserContext(), command_line);
|
||||||
|
|
||||||
|
auto context_id = atom::api::WebContents::GetIDForContents(
|
||||||
|
web_contents);
|
||||||
|
command_line->AppendSwitchASCII(switches::kContextId,
|
||||||
|
base::IntToString(context_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,9 @@ const char kAppUserModelId[] = "app-user-model-id";
|
||||||
// The application path
|
// The application path
|
||||||
const char kAppPath[] = "app-path";
|
const char kAppPath[] = "app-path";
|
||||||
|
|
||||||
|
// The context ID for this process
|
||||||
|
const char kContextId[] = "context-id";
|
||||||
|
|
||||||
// The command line switch versions of the options.
|
// The command line switch versions of the options.
|
||||||
const char kBackgroundColor[] = "background-color";
|
const char kBackgroundColor[] = "background-color";
|
||||||
const char kPreloadScript[] = "preload";
|
const char kPreloadScript[] = "preload";
|
||||||
|
|
|
@ -88,6 +88,7 @@ extern const char kRegisterServiceWorkerSchemes[];
|
||||||
extern const char kSecureSchemes[];
|
extern const char kSecureSchemes[];
|
||||||
extern const char kAppUserModelId[];
|
extern const char kAppUserModelId[];
|
||||||
extern const char kAppPath[];
|
extern const char kAppPath[];
|
||||||
|
extern const char kContextId[];
|
||||||
|
|
||||||
extern const char kBackgroundColor[];
|
extern const char kBackgroundColor[];
|
||||||
extern const char kPreloadScript[];
|
extern const char kPreloadScript[];
|
||||||
|
|
|
@ -394,8 +394,8 @@ ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
|
||||||
objectsRegistry.remove(event.sender.getId(), id)
|
objectsRegistry.remove(event.sender.getId(), id)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (e) => {
|
ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (e, contextId) => {
|
||||||
objectsRegistry.clear(e.sender.getId())
|
objectsRegistry.clear(contextId)
|
||||||
e.returnValue = null
|
e.returnValue = null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', (event, id) => {
|
||||||
|
|
||||||
process.on('exit', () => {
|
process.on('exit', () => {
|
||||||
const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE'
|
const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE'
|
||||||
ipcRenderer.sendSync(command)
|
ipcRenderer.sendSync(command, initialContext)
|
||||||
})
|
})
|
||||||
|
|
||||||
exports.require = (module) => {
|
exports.require = (module) => {
|
||||||
|
@ -295,6 +295,15 @@ exports.getCurrentWebContents = () => {
|
||||||
return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS'))
|
return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CONTEXT_ARG = '--context-id='
|
||||||
|
let initialContext = process.argv.find(arg => arg.startsWith(CONTEXT_ARG))
|
||||||
|
if (initialContext) {
|
||||||
|
initialContext = parseInt(initialContext.substr(CONTEXT_ARG.length), 10)
|
||||||
|
} else {
|
||||||
|
// In sandbox we need to pull this from remote
|
||||||
|
initialContext = exports.getCurrentWebContents().getId()
|
||||||
|
}
|
||||||
|
|
||||||
// Get a global object in browser.
|
// Get a global object in browser.
|
||||||
exports.getGlobal = (name) => {
|
exports.getGlobal = (name) => {
|
||||||
const command = 'ELECTRON_BROWSER_GLOBAL'
|
const command = 'ELECTRON_BROWSER_GLOBAL'
|
||||||
|
|
Loading…
Reference in a new issue