11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci// Before https://github.com/nodejs/node/pull/2847 a child process trying 51cb0ef41Sopenharmony_ci// (asynchronously) to use the closed channel to it's creator caused a segfault. 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst assert = require('assert'); 81cb0ef41Sopenharmony_ciconst cluster = require('cluster'); 91cb0ef41Sopenharmony_ciconst net = require('net'); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciif (!cluster.isPrimary) { 121cb0ef41Sopenharmony_ci // Exit on first received handle to leave the queue non-empty in primary 131cb0ef41Sopenharmony_ci process.on('message', function() { 141cb0ef41Sopenharmony_ci process.exit(1); 151cb0ef41Sopenharmony_ci }); 161cb0ef41Sopenharmony_ci return; 171cb0ef41Sopenharmony_ci} 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst server = net 201cb0ef41Sopenharmony_ci .createServer(function(s) { 211cb0ef41Sopenharmony_ci if (common.isWindows) { 221cb0ef41Sopenharmony_ci s.on('error', function(err) { 231cb0ef41Sopenharmony_ci // Prevent possible ECONNRESET errors from popping up 241cb0ef41Sopenharmony_ci if (err.code !== 'ECONNRESET') throw err; 251cb0ef41Sopenharmony_ci }); 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci setTimeout(function() { 281cb0ef41Sopenharmony_ci s.destroy(); 291cb0ef41Sopenharmony_ci }, 100); 301cb0ef41Sopenharmony_ci }) 311cb0ef41Sopenharmony_ci .listen(0, function() { 321cb0ef41Sopenharmony_ci const worker = cluster.fork(); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci worker.on('error', function(err) { 351cb0ef41Sopenharmony_ci if ( 361cb0ef41Sopenharmony_ci err.code !== 'ECONNRESET' && 371cb0ef41Sopenharmony_ci err.code !== 'ECONNREFUSED' && 381cb0ef41Sopenharmony_ci err.code !== 'EMFILE' 391cb0ef41Sopenharmony_ci ) { 401cb0ef41Sopenharmony_ci throw err; 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci }); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci function send(callback) { 451cb0ef41Sopenharmony_ci const s = net.connect(server.address().port, function() { 461cb0ef41Sopenharmony_ci worker.send({}, s, callback); 471cb0ef41Sopenharmony_ci }); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci // https://github.com/nodejs/node/issues/3635#issuecomment-157714683 501cb0ef41Sopenharmony_ci // ECONNREFUSED or ECONNRESET errors can happen if this connection is 511cb0ef41Sopenharmony_ci // still establishing while the server has already closed. 521cb0ef41Sopenharmony_ci // EMFILE can happen if the worker __and__ the server had already closed. 531cb0ef41Sopenharmony_ci s.on('error', function(err) { 541cb0ef41Sopenharmony_ci if ( 551cb0ef41Sopenharmony_ci err.code !== 'ECONNRESET' && 561cb0ef41Sopenharmony_ci err.code !== 'ECONNREFUSED' && 571cb0ef41Sopenharmony_ci err.code !== 'EMFILE' 581cb0ef41Sopenharmony_ci ) { 591cb0ef41Sopenharmony_ci throw err; 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci }); 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci worker.process.once( 651cb0ef41Sopenharmony_ci 'close', 661cb0ef41Sopenharmony_ci common.mustCall(function() { 671cb0ef41Sopenharmony_ci // Otherwise the crash on `channel.fd` access may happen 681cb0ef41Sopenharmony_ci assert.strictEqual(worker.process.channel, null); 691cb0ef41Sopenharmony_ci server.close(); 701cb0ef41Sopenharmony_ci }) 711cb0ef41Sopenharmony_ci ); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci worker.on('online', function() { 741cb0ef41Sopenharmony_ci send(function(err) { 751cb0ef41Sopenharmony_ci assert.ifError(err); 761cb0ef41Sopenharmony_ci send(function(err) { 771cb0ef41Sopenharmony_ci // Ignore errors when sending the second handle because the worker 781cb0ef41Sopenharmony_ci // may already have exited. 791cb0ef41Sopenharmony_ci if (err && err.code !== 'ERR_IPC_CHANNEL_CLOSED' && 801cb0ef41Sopenharmony_ci err.code !== 'ECONNRESET' && 811cb0ef41Sopenharmony_ci err.code !== 'ECONNREFUSED' && 821cb0ef41Sopenharmony_ci err.code !== 'EMFILE') { 831cb0ef41Sopenharmony_ci throw err; 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci }); 861cb0ef41Sopenharmony_ci }); 871cb0ef41Sopenharmony_ci }); 881cb0ef41Sopenharmony_ci }); 89