From 0d30546329e3fde5b798736817b4a5fcdb7b87ec Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Mon, 27 Jan 2020 22:09:23 -0500 Subject: [PATCH] net: track state of setNoDelay() and prevent unnecessary system calls The state of .setNoDelay() is now tracked and code will prevent repeated system calls to setsockopt() when the value has already been set to the desired value for the socket. Change and expand the appropriate test. PR-URL: https://github.com/nodejs/node/pull/31543 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca --- lib/net.js | 10 +++++++--- test/parallel/test-net-socket-setnodelay.js | 12 ++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/net.js b/lib/net.js index b32937f224b873..21d17702b53798 100644 --- a/lib/net.js +++ b/lib/net.js @@ -257,7 +257,7 @@ function initSocketHandle(self) { const kBytesRead = Symbol('kBytesRead'); const kBytesWritten = Symbol('kBytesWritten'); - +const kSetNoDelay = Symbol('kSetNoDelay'); function Socket(options) { if (!(this instanceof Socket)) return new Socket(options); @@ -271,6 +271,7 @@ function Socket(options) { this[kHandle] = null; this._parent = null; this._host = null; + this[kSetNoDelay] = false; this[kLastWriteQueueSize] = 0; this[kTimeout] = null; this[kBuffer] = null; @@ -487,8 +488,11 @@ Socket.prototype.setNoDelay = function(enable) { } // Backwards compatibility: assume true when `enable` is omitted - if (this._handle.setNoDelay) - this._handle.setNoDelay(enable === undefined ? true : !!enable); + const newValue = enable === undefined ? true : !!enable; + if (this._handle.setNoDelay && newValue !== this[kSetNoDelay]) { + this[kSetNoDelay] = newValue; + this._handle.setNoDelay(newValue); + } return this; }; diff --git a/test/parallel/test-net-socket-setnodelay.js b/test/parallel/test-net-socket-setnodelay.js index 55b4c773fa5bf7..e11d89daec58de 100644 --- a/test/parallel/test-net-socket-setnodelay.js +++ b/test/parallel/test-net-socket-setnodelay.js @@ -20,18 +20,26 @@ socket.setNoDelay(); socket = new net.Socket({ handle: { - setNoDelay: common.mustCall(genSetNoDelay(true), truthyValues.length) + setNoDelay: common.mustCall(genSetNoDelay(true), 1) } }); truthyValues.forEach((testVal) => socket.setNoDelay(testVal)); socket = new net.Socket({ handle: { - setNoDelay: common.mustCall(genSetNoDelay(false), falseyValues.length) + setNoDelay: common.mustNotCall() } }); falseyValues.forEach((testVal) => socket.setNoDelay(testVal)); +socket = new net.Socket({ + handle: { + setNoDelay: common.mustCall(() => {}, 3) + } +}); +truthyValues.concat(falseyValues).concat(truthyValues) + .forEach((testVal) => socket.setNoDelay(testVal)); + // If a handler doesn't have a setNoDelay function it shouldn't be called. // In the case below, if it is called an exception will be thrown socket = new net.Socket({