diff --git a/lib/net.js b/lib/net.js index d2b510c64bbb..63bb811c5bd5 100644 --- a/lib/net.js +++ b/lib/net.js @@ -172,6 +172,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'); @@ -1088,13 +1089,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 000000000000..cb2086bc547c --- /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);