mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-27 18:17:22 +02:00
LibWeb: Use last promise to wait for pending writes ReadableStreamPipeTo
ReadableStreamPipeTo is used in fetching, and previously requests with large bodies could lead to tens of thousands of pending write promises being accumulated in `m_pending_writes`. With this change, instead of accumulating all pending write promises up until pipe shutdown, we only keep track of the last one and use it to determine whether there are pending writes when we need to shut down the pipe.
This commit is contained in:
committed by
Tim Flynn
parent
77cab84620
commit
18089937a5
Notes:
github-actions[bot]
2025-12-08 16:46:22 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/18089937a52 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7059 Reviewed-by: https://github.com/trflynn89 ✅
@@ -100,7 +100,7 @@ void ReadableStreamPipeTo::visit_edges(Cell::Visitor& visitor)
|
||||
visitor.visit(m_reader);
|
||||
visitor.visit(m_writer);
|
||||
visitor.visit(m_signal);
|
||||
visitor.visit(m_pending_writes);
|
||||
visitor.visit(m_last_write_promise);
|
||||
visitor.visit(m_unwritten_chunks);
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ void ReadableStreamPipeTo::write_chunk()
|
||||
auto promise = writable_stream_default_writer_write(m_writer, m_unwritten_chunks.take_first());
|
||||
WebIDL::mark_promise_as_handled(promise);
|
||||
|
||||
m_pending_writes.append(promise);
|
||||
m_last_write_promise = promise;
|
||||
}
|
||||
|
||||
void ReadableStreamPipeTo::write_unwritten_chunks()
|
||||
@@ -269,15 +269,19 @@ void ReadableStreamPipeTo::write_unwritten_chunks()
|
||||
|
||||
void ReadableStreamPipeTo::wait_for_pending_writes_to_complete(Function<void()> on_complete)
|
||||
{
|
||||
auto handler = GC::create_function(heap(), [this, on_complete = move(on_complete)]() {
|
||||
m_pending_writes.clear();
|
||||
auto last_write_promise = m_last_write_promise;
|
||||
m_last_write_promise = {};
|
||||
if (!last_write_promise) {
|
||||
HTML::queue_a_microtask(nullptr, GC::create_function(heap(), [on_complete = move(on_complete)]() {
|
||||
on_complete();
|
||||
}));
|
||||
return;
|
||||
}
|
||||
auto run_complete_steps = GC::create_function(heap(), [on_complete = move(on_complete)](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||
on_complete();
|
||||
return JS::js_undefined();
|
||||
});
|
||||
|
||||
auto success_steps = [handler](Vector<JS::Value> const&) { handler->function()(); };
|
||||
auto failure_steps = [handler](JS::Value) { handler->function()(); };
|
||||
|
||||
WebIDL::wait_for_all(m_realm, m_pending_writes, move(success_steps), move(failure_steps));
|
||||
WebIDL::react_to_promise(*last_write_promise, run_complete_steps, run_complete_steps);
|
||||
}
|
||||
|
||||
// https://streams.spec.whatwg.org/#rs-pipeTo-finalize
|
||||
|
||||
Reference in New Issue
Block a user