Skip to content

Commit 64a762b

Browse files
pimterrypanva
authored andcommitted
stream: fix flaky stream destroy, reachable from HTTP/2 teardown
Signed-off-by: Tim Perry <[email protected]> PR-URL: nodejs#65079 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Filip Skokan <[email protected]>
1 parent 780229b commit 64a762b

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

src/stream_pipe.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ void StreamPipe::Unpipe(bool is_in_deletion) {
5858

5959
is_closed_ = true;
6060
is_reading_ = false;
61-
source()->RemoveStreamListener(&readable_listener_);
61+
// Source may already be gone here during destroy
62+
if (source() != nullptr) source()->RemoveStreamListener(&readable_listener_);
6263
if (pending_writes_ == 0 || sink_destroyed_)
6364
sink()->RemoveStreamListener(&writable_listener_);
6465

@@ -209,8 +210,14 @@ void StreamPipe::WritableListener::OnStreamAfterShutdown(ShutdownWrap* w,
209210
void StreamPipe::ReadableListener::OnStreamDestroy() {
210211
StreamPipe* pipe = ContainerOf(&StreamPipe::readable_listener_, this);
211212
pipe->source_destroyed_ = true;
212-
if (!pipe->is_eof_) {
213-
OnStreamRead(UV_EPIPE, uv_buf_init(nullptr, 0));
213+
if (pipe->is_eof_) return;
214+
215+
// Mirror ReadableListener::OnStreamRead() teardown, but without
216+
// other stream interactions:
217+
pipe->is_eof_ = true;
218+
if (pipe->pending_writes_ == 0) {
219+
pipe->sink()->Shutdown();
220+
pipe->Unpipe();
214221
}
215222
}
216223

@@ -227,8 +234,7 @@ void StreamPipe::WritableListener::OnStreamDestroy() {
227234
void StreamPipe::WritableListener::OnStreamWantsWrite(size_t suggested_size) {
228235
StreamPipe* pipe = ContainerOf(&StreamPipe::writable_listener_, this);
229236
pipe->wanted_data_ = suggested_size;
230-
if (pipe->is_reading_ || pipe->is_closed_)
231-
return;
237+
if (pipe->is_reading_ || pipe->is_closed_ || pipe->source_destroyed_) return;
232238
HandleScope handle_scope(pipe->env()->isolate());
233239
InternalCallbackScope callback_scope(pipe,
234240
InternalCallbackScope::kSkipTaskQueues);

0 commit comments

Comments
 (0)