@@ -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,
209210void 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() {
227234void 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