mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-24 00:20:21 +00:00
LibWeb: Queue the task for MessagePort receive in targetPort's realm
We were delaying sending an IPC message until the HTML PortMessage task was run, but we were not queuing the task in on the receiver side. The result of this was that message port posting was needlessly creating an HTML task just to send an IPC message. On the flip side, we were directly calling dispatch_event from the socket notifier of the target port's message queue. This is a huge problem, because it means that we were effectively running javascript-aware code from an 'in parallel' context. By switching around which side of the IPC interface is responsible for queuing a task, we can avoid problems where a document is destroyed from a port message-attached callback and crashes.
This commit is contained in:
parent
6709905656
commit
85515c0096
Notes:
github-actions[bot]
2024-11-09 13:19:38 +00:00
Author: https://github.com/ADKaster Commit: https://github.com/LadybirdBrowser/ladybird/commit/85515c0096c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2243
1 changed files with 11 additions and 10 deletions
|
@ -280,15 +280,12 @@ ErrorOr<void> MessagePort::send_message_on_transport(SerializedTransferRecord co
|
|||
|
||||
void MessagePort::post_port_message(SerializedTransferRecord serialize_with_transfer_result)
|
||||
{
|
||||
// FIXME: Use the correct task source?
|
||||
queue_global_task(Task::Source::PostedMessage, relevant_global_object(*this), JS::create_heap_function(heap(), [this, serialize_with_transfer_result = move(serialize_with_transfer_result)]() mutable {
|
||||
if (!m_transport.has_value() || !m_transport->is_open())
|
||||
return;
|
||||
if (auto result = send_message_on_transport(serialize_with_transfer_result); result.is_error()) {
|
||||
dbgln("Failed to post message: {}", result.error());
|
||||
disentangle();
|
||||
}
|
||||
}));
|
||||
if (!m_transport.has_value() || !m_transport->is_open())
|
||||
return;
|
||||
if (auto result = send_message_on_transport(serialize_with_transfer_result); result.is_error()) {
|
||||
dbgln("Failed to post message: {}", result.error());
|
||||
disentangle();
|
||||
}
|
||||
}
|
||||
|
||||
ErrorOr<MessagePort::ParseDecision> MessagePort::parse_message()
|
||||
|
@ -324,7 +321,11 @@ ErrorOr<MessagePort::ParseDecision> MessagePort::parse_message()
|
|||
|
||||
m_buffered_data.remove(0, HEADER_SIZE + m_socket_incoming_message_size);
|
||||
|
||||
post_message_task_steps(serialized_transfer_record);
|
||||
// Note: this is step 7 of message_port_post_message_steps:
|
||||
// 7. Add a task that runs the following steps to the port message queue of targetPort:
|
||||
queue_global_task(Task::Source::PostedMessage, relevant_global_object(*this), JS::create_heap_function(heap(), [this, serialized_transfer_record = move(serialized_transfer_record)]() mutable {
|
||||
this->post_message_task_steps(serialized_transfer_record);
|
||||
}));
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue