diff --git a/lib/net.js b/lib/net.js index a391e9da30f861..36b0863fa32a5d 100644 --- a/lib/net.js +++ b/lib/net.js @@ -152,6 +152,7 @@ const DEFAULT_IPV6_ADDR = '::'; const noop = () => {}; const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext'); +const kDestroyingOnFinish = Symbol('kDestroyingOnFinish'); const dc = require('diagnostics_channel'); const netClientSocketChannel = dc.channel('net.client.socket'); @@ -795,13 +796,20 @@ function onReadableStreamEnd() { Socket.prototype.destroySoon = function() { + if (this[kDestroyingOnFinish]) return; + if (this.writable) this.end(); if (this.writableFinished) this.destroy(); - else - this.once('finish', this.destroy); + else { + this[kDestroyingOnFinish] = true; + this.once('finish', () => { + this[kDestroyingOnFinish] = false; + this.destroy(); + }); + } }; diff --git a/test/parallel/test-net-socket-not-duplicates-destroy-soon-listeners.js b/test/parallel/test-net-socket-not-duplicates-destroy-soon-listeners.js new file mode 100644 index 00000000000000..cb2086bc547ccf --- /dev/null +++ b/test/parallel/test-net-socket-not-duplicates-destroy-soon-listeners.js @@ -0,0 +1,10 @@ +'use strict'; +require('../common'); + +const assert = require('assert'); +const { Socket } = require('net'); + +const socket = new Socket(); +socket.destroySoon(); +socket.destroySoon(); +assert.strictEqual(socket.listeners('finish').length, 1);