Skip to content

Commit

Permalink
net: track state of setNoDelay() and prevent unnecessary system calls
Browse files Browse the repository at this point in the history
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: #31543
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
  • Loading branch information
rustyconover authored and codebytere committed Mar 17, 2020
1 parent 8622ee0 commit 40f57da
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
10 changes: 7 additions & 3 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
};
Expand Down
12 changes: 10 additions & 2 deletions test/parallel/test-net-socket-setnodelay.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down

0 comments on commit 40f57da

Please sign in to comment.