-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
child_process: workaround fd passing issue on OS X
There's an issue on some `OS X` versions when passing fd's between processes. When the handle associated to a specific file descriptor is closed by the sender process before it's received in the destination, the handle is indeed closed while it should remain opened. In order to fix this behaviour, don't close the handle until the `NODE_HANDLE_ACK` is received by the sender. Added `test-child-process-pass-fd` that is basically `test-cluster-net-send` but creating lots of workers, so the issue reproduces on `OS X` consistently. Fixes: #7512 Ref: #8904 PR-URL: #7572 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
- Loading branch information
1 parent
6effc4a
commit 5ed5142
Showing
2 changed files
with
86 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use strict'; | ||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const fork = require('child_process').fork; | ||
const net = require('net'); | ||
|
||
if ((process.config.variables.arm_version === '6') || | ||
(process.config.variables.arm_version === '7')) { | ||
common.skip('Too slow for armv6 and armv7 bots'); | ||
return; | ||
} | ||
|
||
const N = 80; | ||
|
||
if (process.argv[2] !== 'child') { | ||
for (let i = 0; i < N; ++i) { | ||
const worker = fork(__filename, ['child', common.PORT + i]); | ||
worker.once('message', common.mustCall((msg, handle) => { | ||
assert.strictEqual(msg, 'handle'); | ||
assert.ok(handle); | ||
worker.send('got'); | ||
|
||
let recvData = ''; | ||
handle.on('data', common.mustCall((data) => { | ||
recvData += data; | ||
})); | ||
|
||
handle.on('end', () => { | ||
assert.strictEqual(recvData, 'hello'); | ||
worker.kill(); | ||
}); | ||
})); | ||
} | ||
} else { | ||
let socket; | ||
const port = process.argv[3]; | ||
let cbcalls = 0; | ||
function socketConnected() { | ||
if (++cbcalls === 2) | ||
process.send('handle', socket); | ||
} | ||
|
||
const server = net.createServer((c) => { | ||
process.once('message', function(msg) { | ||
assert.strictEqual(msg, 'got'); | ||
c.end('hello'); | ||
}); | ||
socketConnected(); | ||
}); | ||
server.listen(port, common.localhostIPv4, () => { | ||
socket = net.connect(port, common.localhostIPv4, socketConnected); | ||
}); | ||
} |