From c3fff2511588e01da38dd84be4312f8a2c1f4616 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 26 Nov 2019 17:08:11 +0100 Subject: [PATCH] src: no SetImmediate from destructor in stream_pipe code Guard against running `SetImmediate()` from the destructor. The object will not be alive or usable in the callback, so it does not make sense to attempt to schedule the `SetImmediate()`. PR-URL: https://github.com/nodejs/node/pull/30666 Fixes: https://github.com/nodejs/node/issues/30643 Refs: https://github.com/nodejs/node/pull/30374 Reviewed-By: Rich Trott Reviewed-By: James M Snell --- src/stream_pipe.cc | 6 ++++-- src/stream_pipe.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/stream_pipe.cc b/src/stream_pipe.cc index 7c10f4a5588cad..5f7514b1b84790 100644 --- a/src/stream_pipe.cc +++ b/src/stream_pipe.cc @@ -42,7 +42,7 @@ StreamPipe::StreamPipe(StreamBase* source, } StreamPipe::~StreamPipe() { - Unpipe(); + Unpipe(true); } StreamBase* StreamPipe::source() { @@ -53,7 +53,7 @@ StreamBase* StreamPipe::sink() { return static_cast(writable_listener_.stream()); } -void StreamPipe::Unpipe() { +void StreamPipe::Unpipe(bool is_in_deletion) { if (is_closed_) return; @@ -69,6 +69,8 @@ void StreamPipe::Unpipe() { if (pending_writes_ == 0) sink()->RemoveStreamListener(&writable_listener_); + if (is_in_deletion) return; + // Delay the JS-facing part with SetImmediate, because this might be from // inside the garbage collector, so we can’t run JS here. HandleScope handle_scope(env()->isolate()); diff --git a/src/stream_pipe.h b/src/stream_pipe.h index 4cc5668c4c5137..e22abab0115c8a 100644 --- a/src/stream_pipe.h +++ b/src/stream_pipe.h @@ -12,7 +12,7 @@ class StreamPipe : public AsyncWrap { StreamPipe(StreamBase* source, StreamBase* sink, v8::Local obj); ~StreamPipe() override; - void Unpipe(); + void Unpipe(bool is_in_deletion = false); static void New(const v8::FunctionCallbackInfo& args); static void Start(const v8::FunctionCallbackInfo& args);