diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 9ad7bf8fd8593c..551ba3bdcea2aa 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -691,9 +691,10 @@ function setupChannel(target, channel, serializationMode) { const obj = handleConversion[message.type]; - // Update simultaneous accepts on Windows - if (process.platform === 'win32') { - handle.setSimultaneousAccepts(false); + // Call setSimultaneousAccepts if it is a function + // currently, it is only defined in tcp_wrap.cc and on win32 + if (obj.simultaneousAccepts && typeof handle.setSimultaneousAccepts === 'function') { + handle.setSimultaneousAccepts(true); } // Convert handle object @@ -816,8 +817,11 @@ function setupChannel(target, channel, serializationMode) { if (!handle) message = message.msg; - // Update simultaneous accepts on Windows - if (obj.simultaneousAccepts && process.platform === 'win32') { + // Call setSimultaneousAccepts if it is a function + // currently, it is only defined in tcp_wrap.cc and on win32 + if (handle && + obj.simultaneousAccepts && + typeof handle.setSimultaneousAccepts === 'function') { handle.setSimultaneousAccepts(true); } } else if (this._handleQueue && diff --git a/lib/net.js b/lib/net.js index d6e0ad679fd5ea..b6e5b03bbdb7c1 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1890,7 +1890,8 @@ if (isWindows) { process.env.NODE_MANY_ACCEPTS !== '0'); } - if (handle._simultaneousAccepts !== simultaneousAccepts) { + if (handle._simultaneousAccepts !== simultaneousAccepts && + typeof handle.setSimultaneousAccepts === 'function') { handle.setSimultaneousAccepts(!!simultaneousAccepts); handle._simultaneousAccepts = simultaneousAccepts; } diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 1f81094d32b829..73d34bb5b0d86f 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -207,6 +207,9 @@ void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo& args) { ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder(), args.GetReturnValue().Set(UV_EBADF)); + if (wrap->provider_type() != ProviderType::PROVIDER_TCPSERVERWRAP) { + return; + } bool enable = args[0]->IsTrue(); int err = uv_tcp_simultaneous_accepts(&wrap->handle_, enable); args.GetReturnValue().Set(err); diff --git a/test/parallel/test-setsimultaneousaccepts.js b/test/parallel/test-setsimultaneousaccepts.js new file mode 100644 index 00000000000000..564a7f0fa1f076 --- /dev/null +++ b/test/parallel/test-setsimultaneousaccepts.js @@ -0,0 +1,54 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const child_process = require('child_process'); + +const CODE = ` + const net = require('net'); + process.on('message', (message, handle) => { + // net.Socket or net.Server + handle instanceof net.Socket ? handle.destroy() : handle.close(); + process.send('accepted'); + }) +`; + +const child = child_process.fork(process.execPath, { execArgv: ['-e', CODE ] }); + +let tcpServer; +const sockets = []; +let accepted = 0; + +child.on('message', (message) => { + assert.strictEqual(message, 'accepted'); + if (++accepted === 2) { + child.kill(); + tcpServer.close(); + sockets.forEach((socket) => { + socket.destroy(); + }); + } +}); + +tcpServer = net.createServer(common.mustCall((socket) => { + const setSimultaneousAccepts = socket._handle.setSimultaneousAccepts; + if (typeof setSimultaneousAccepts === 'function') { + socket._handle.setSimultaneousAccepts = common.mustCall((...args) => { + const ret = setSimultaneousAccepts.call(socket._handle, ...args); + assert.strictEqual(ret, undefined); + }); + } + child.send(null, socket._handle); + sockets.push(socket); +})); +tcpServer.listen(0, common.mustCall(() => { + net.connect(tcpServer.address().port); + const setSimultaneousAccepts = tcpServer._handle.setSimultaneousAccepts; + if (typeof setSimultaneousAccepts === 'function') { + tcpServer._handle.setSimultaneousAccepts = common.mustCall((...args) => { + const ret = setSimultaneousAccepts.call(tcpServer._handle, ...args); + assert.strictEqual(ret, 0); + }); + } + child.send(null, tcpServer); +}));