fix: use OS process handle to clear object registry (#14364)
RenderProcessHost switch can happen between ipc calls when speculative process are invvolved, which will lead to deletion of entries on current context. Use OS process handles to uniquely associate a destruction handler for a render process.
This commit is contained in:
parent
3301e05f33
commit
ccf8a797dc
4 changed files with 10 additions and 7 deletions
|
@ -766,7 +766,8 @@ void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||||
Emit("render-view-deleted", render_view_host->GetProcess()->GetID());
|
Emit("render-view-deleted", render_view_host->GetProcess()->GetID(),
|
||||||
|
base::GetProcId(render_view_host->GetProcess()->GetHandle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "atom/renderer/content_settings_observer.h"
|
#include "atom/renderer/content_settings_observer.h"
|
||||||
#include "atom/renderer/preferences_manager.h"
|
#include "atom/renderer/preferences_manager.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/process/process_handle.h"
|
#include "base/process/process.h"
|
||||||
#include "base/strings/string_split.h"
|
#include "base/strings/string_split.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "chrome/renderer/media/chrome_key_systems.h"
|
#include "chrome/renderer/media/chrome_key_systems.h"
|
||||||
|
@ -94,7 +94,8 @@ void RendererClientBase::DidCreateScriptContext(
|
||||||
content::RenderFrame* render_frame) {
|
content::RenderFrame* render_frame) {
|
||||||
// global.setHidden("contextId", `${processId}-${++nextContextId}`)
|
// global.setHidden("contextId", `${processId}-${++nextContextId}`)
|
||||||
std::string context_id = base::StringPrintf(
|
std::string context_id = base::StringPrintf(
|
||||||
"%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_);
|
"%" CrPRIdPid "-%d", base::GetProcId(base::Process::Current().Handle()),
|
||||||
|
++next_context_id_);
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId");
|
v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId");
|
||||||
v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key);
|
v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key);
|
||||||
|
|
|
@ -98,9 +98,10 @@ class ObjectsRegistry {
|
||||||
|
|
||||||
// Private: Clear the storage when renderer process is destoryed.
|
// Private: Clear the storage when renderer process is destoryed.
|
||||||
registerDeleteListener (webContents, contextId) {
|
registerDeleteListener (webContents, contextId) {
|
||||||
const processId = webContents.getProcessId()
|
// contextId => ${OSProcessId}-${contextCount}
|
||||||
const listener = (event, deletedProcessId) => {
|
const OSProcessId = contextId.split('-')[0]
|
||||||
if (deletedProcessId === processId) {
|
const listener = (event, deletedProcessId, deletedOSProcessId) => {
|
||||||
|
if (deletedOSProcessId && deletedOSProcessId.toString() === OSProcessId) {
|
||||||
webContents.removeListener('render-view-deleted', listener)
|
webContents.removeListener('render-view-deleted', listener)
|
||||||
this.clear(webContents, contextId)
|
this.clear(webContents, contextId)
|
||||||
}
|
}
|
||||||
|
|
2
spec/fixtures/api/render-view-deleted.html
vendored
2
spec/fixtures/api/render-view-deleted.html
vendored
|
@ -17,7 +17,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should trigger a dereference and a remote getURL call should fail
|
// This should trigger a dereference and a remote getURL call should fail
|
||||||
contents.emit('render-view-deleted', {}, contents.getProcessId())
|
contents.emit('render-view-deleted', {}, '', contents.getOSProcessId())
|
||||||
try {
|
try {
|
||||||
contents.getURL()
|
contents.getURL()
|
||||||
ipcRenderer.send('error-message', 'No error thrown')
|
ipcRenderer.send('error-message', 'No error thrown')
|
||||||
|
|
Loading…
Reference in a new issue