fix: ensure MessagePorts get GCed when not referenced (#40189)
This commit is contained in:
parent
5d6023ae0d
commit
bbd2236bdd
3 changed files with 75 additions and 5 deletions
|
@ -135,3 +135,4 @@ fix_activate_background_material_on_windows.patch
|
||||||
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
|
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
|
||||||
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
|
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
|
||||||
fix_handle_no_top_level_aura_window_in_webcontentsimpl.patch
|
fix_handle_no_top_level_aura_window_in_webcontentsimpl.patch
|
||||||
|
ensure_messageports_get_gced_when_not_referenced.patch
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yoav Weiss <yoavweiss@chromium.org>
|
||||||
|
Date: Mon, 9 Oct 2023 14:21:44 +0000
|
||||||
|
Subject: Ensure MessagePorts get GCed when not referenced
|
||||||
|
|
||||||
|
[1] regressed MessagePort memory and caused them to no longer be
|
||||||
|
collected after not being referenced.
|
||||||
|
This CL fixes that by turning the mutual pointers between attached
|
||||||
|
MessagePorts to be WeakMembers.
|
||||||
|
|
||||||
|
[1] https://chromium-review.googlesource.com/4919476
|
||||||
|
|
||||||
|
Bug: 1487835
|
||||||
|
Change-Id: Icd7eba09a217ad5d588958504d5c4794d7d8a295
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4919476
|
||||||
|
Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
|
||||||
|
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1207067}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/messaging/message_port.cc b/third_party/blink/renderer/core/messaging/message_port.cc
|
||||||
|
index 0fd5bbf170efa02d3e710de3cb6733158faec858..15f5f0f6aa05d3b17adae87286c92df9cc26a712 100644
|
||||||
|
--- a/third_party/blink/renderer/core/messaging/message_port.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/messaging/message_port.cc
|
||||||
|
@@ -162,8 +162,10 @@ MessagePortChannel MessagePort::Disentangle() {
|
||||||
|
DCHECK(!IsNeutered());
|
||||||
|
port_descriptor_.GiveDisentangledHandle(connector_->PassMessagePipe());
|
||||||
|
connector_ = nullptr;
|
||||||
|
- if (initially_entangled_port_) {
|
||||||
|
- initially_entangled_port_->OnEntangledPortDisconnected();
|
||||||
|
+ // Using a variable here places the WeakMember pointer on the stack, ensuring
|
||||||
|
+ // it doesn't get GCed while it's being used.
|
||||||
|
+ if (auto* entangled_port = initially_entangled_port_.Get()) {
|
||||||
|
+ entangled_port->OnEntangledPortDisconnected();
|
||||||
|
}
|
||||||
|
OnEntangledPortDisconnected();
|
||||||
|
return MessagePortChannel(std::move(port_descriptor_));
|
||||||
|
@@ -340,7 +342,10 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
|
||||||
|
// lifetime of this function.
|
||||||
|
std::unique_ptr<scheduler::TaskAttributionTracker::TaskScope>
|
||||||
|
task_attribution_scope;
|
||||||
|
- if (initially_entangled_port_ && message.sender_origin &&
|
||||||
|
+ // Using a variable here places the WeakMember pointer on the stack, ensuring
|
||||||
|
+ // it doesn't get GCed while it's being used.
|
||||||
|
+ auto* entangled_port = initially_entangled_port_.Get();
|
||||||
|
+ if (entangled_port && message.sender_origin &&
|
||||||
|
message.sender_origin->IsSameOriginWith(context->GetSecurityOrigin()) &&
|
||||||
|
context->IsSameAgentCluster(message.sender_agent_cluster_id) &&
|
||||||
|
context->IsWindow()) {
|
||||||
|
@@ -364,9 +369,9 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
|
||||||
|
ThreadScheduler::Current()->GetTaskAttributionTracker()) {
|
||||||
|
// Since `initially_entangled_port_` is not nullptr, neither should be
|
||||||
|
// its `post_message_task_container_`.
|
||||||
|
- CHECK(initially_entangled_port_->post_message_task_container_);
|
||||||
|
+ CHECK(entangled_port->post_message_task_container_);
|
||||||
|
scheduler::TaskAttributionInfo* parent_task =
|
||||||
|
- initially_entangled_port_->post_message_task_container_
|
||||||
|
+ entangled_port->post_message_task_container_
|
||||||
|
->GetAndDecrementPostMessageTask(message.parent_task_id);
|
||||||
|
task_attribution_scope = tracker->CreateTaskScope(
|
||||||
|
script_state, parent_task,
|
||||||
|
diff --git a/third_party/blink/renderer/core/messaging/message_port.h b/third_party/blink/renderer/core/messaging/message_port.h
|
||||||
|
index 98ed58a9a765f5101d9b421507bf25db4359d7e5..a178d15c11b1e5fb1ff74d182021fe39e9d9b107 100644
|
||||||
|
--- a/third_party/blink/renderer/core/messaging/message_port.h
|
||||||
|
+++ b/third_party/blink/renderer/core/messaging/message_port.h
|
||||||
|
@@ -195,7 +195,7 @@ class CORE_EXPORT MessagePort : public EventTarget,
|
||||||
|
|
||||||
|
// The entangled port. Only set on initial entanglement, and gets unset as
|
||||||
|
// soon as the ports are disentangled.
|
||||||
|
- Member<MessagePort> initially_entangled_port_;
|
||||||
|
+ WeakMember<MessagePort> initially_entangled_port_;
|
||||||
|
|
||||||
|
Member<PostMessageTaskContainer> post_message_task_container_;
|
||||||
|
};
|
|
@ -317,11 +317,7 @@ describe('ipc module', () => {
|
||||||
await once(ipcMain, 'closed');
|
await once(ipcMain, 'closed');
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(@vertedinde): This broke upstream in CL https://chromium-review.googlesource.com/c/chromium/src/+/4831380
|
it('is emitted when the other end of a port is garbage-collected', async () => {
|
||||||
// The behavior seems to be an intentional change, we need to either A) implement the task_container_ model in
|
|
||||||
// our renderer message ports or B) patch how we handle renderer message ports being garbage collected
|
|
||||||
// crbug: https://bugs.chromium.org/p/chromium/issues/detail?id=1487835
|
|
||||||
it.skip('is emitted when the other end of a port is garbage-collected', async () => {
|
|
||||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
|
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
|
||||||
w.loadURL('about:blank');
|
w.loadURL('about:blank');
|
||||||
await w.webContents.executeJavaScript(`(${async function () {
|
await w.webContents.executeJavaScript(`(${async function () {
|
||||||
|
|
Loading…
Reference in a new issue