From 354c8974bba9c7b440797870b0782715bd27e53a Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 18 Aug 2019 23:38:35 +0200 Subject: [PATCH] stream: fix multiple destroy calls Previously destroy could be called multiple times causing inconsistent and hard to predict behavior. Furthermore, since the stream _destroy implementation can only be called once, the behavior of applying destroy multiple times becomes unclear. This changes so that only the first destroy() call is executed and any subsequent calls are noops. --- doc/api/stream.md | 11 +++++++ lib/_tls_wrap.js | 2 +- lib/internal/fs/streams.js | 2 +- lib/internal/streams/destroy.js | 33 ++++++++++--------- test/parallel/test-file-write-stream.js | 3 +- test/parallel/test-file-write-stream2.js | 13 +++----- ...est-http2-server-stream-session-destroy.js | 8 ++--- test/parallel/test-net-socket-destroy-send.js | 6 +--- test/parallel/test-stream-catch-rejections.js | 5 ++- test/parallel/test-stream-pipeline.js | 4 +-- test/parallel/test-stream-readable-destroy.js | 12 +++---- test/parallel/test-stream-writable-destroy.js | 22 +++++-------- .../parallel/test-stream-writable-writable.js | 1 - .../test-stream-writable-write-error.js | 1 - .../test-tls-wrap-econnreset-localaddress.js | 5 +++ .../parallel/test-tls-wrap-econnreset-pipe.js | 5 +++ .../test-tls-wrap-econnreset-socket.js | 5 +++ test/parallel/test-tls-wrap-econnreset.js | 5 +++ test/parallel/test-zlib-write-after-close.js | 7 +--- 19 files changed, 77 insertions(+), 73 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index cf3ecd461c13ed..6a32316d4dbb83 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -385,6 +385,10 @@ This is a destructive and immediate way to destroy a stream. Previous calls to `write()` may not have drained, and may trigger an `ERR_STREAM_DESTROYED` error. Use `end()` instead of destroy if data should flush before close, or wait for the `'drain'` event before destroying the stream. + +Once `destroy()` has been called any further calls will be a noop and no +further errors except from `_destroy` may be emitted as `'error'`. + Implementors should not override this method, but instead implement [`writable._destroy()`][writable-_destroy]. @@ -953,6 +957,10 @@ Destroy the stream. Optionally emit an `'error'` event, and emit a `'close'` event (unless `emitClose` is set to `false`). After this call, the readable stream will release any internal resources and subsequent calls to `push()` will be ignored. + +Once `destroy()` has been called any further calls will be a noop and no +further errors except from `_destroy` may be emitted as `'error'`. + Implementors should not override this method, but instead implement [`readable._destroy()`][readable-_destroy]. @@ -1484,6 +1492,9 @@ Implementors should not override this method, but instead implement The default implementation of `_destroy()` for `Transform` also emit `'close'` unless `emitClose` is set in false. +Once `destroy()` has been called any further calls will be a noop and no +further errors except from `_destroy` may be emitted as `'error'`. + ### `stream.finished(stream[, options], callback)`