Skip to content

Commit d9465ae

Browse files
ErickWendeltargos
authored andcommitted
child_process: queue pending messages
It fixes the problem of the child process not receiving messages. Fixes: #41134 PR-URL: #41221 Reviewed-By: Adrian Estrada <edsadr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
1 parent 75c565b commit d9465ae

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

‎lib/internal/child_process.js‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ let HTTPParser;
8181
constMAX_HANDLE_RETRANSMISSIONS=3;
8282
constkChannelHandle=Symbol('kChannelHandle');
8383
constkIsUsedAsStdio=Symbol('kIsUsedAsStdio');
84+
constkPendingMessages=Symbol('kPendingMessages');
8485

8586
// This object contain function to convert TCP objects to native handle objects
8687
// and back again.
@@ -526,6 +527,7 @@ class Control extends EventEmitter {
526527
constructor(channel){
527528
super();
528529
this.#channel =channel;
530+
this[kPendingMessages]=[];
529531
}
530532

531533
// The methods keeping track of the counter are being used to track the
@@ -699,6 +701,24 @@ function setupChannel(target, channel, serializationMode) {
699701
});
700702
});
701703

704+
target.on('newListener',function(){
705+
706+
process.nextTick(()=>{
707+
if(!target.channel||!target.listenerCount('message'))
708+
return;
709+
710+
constmessages=target.channel[kPendingMessages];
711+
const{ length }=messages;
712+
if(!length)return;
713+
714+
for(leti=0;i<length;i++){
715+
ReflectApply(target.emit,target,messages[i]);
716+
}
717+
718+
target.channel[kPendingMessages]=[];
719+
});
720+
});
721+
702722
target.send=function(message,handle,options,callback){
703723
if(typeofhandle==='function'){
704724
callback=handle;
@@ -912,7 +932,15 @@ function setupChannel(target, channel, serializationMode) {
912932
};
913933

914934
functionemit(event,message,handle){
915-
target.emit(event,message,handle);
935+
if('internalMessage'===event||target.listenerCount('message')){
936+
target.emit(event,message,handle);
937+
return;
938+
}
939+
940+
ArrayPrototypePush(
941+
target.channel[kPendingMessages],
942+
[event,message,handle]
943+
);
916944
}
917945

918946
functionhandleMessage(message,handle,internal){
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import'../common/index.mjs';
2+
importassertfrom'assert';
3+
import{fork}from'child_process';
4+
import{once}from'events';
5+
import{fileURLToPath}from'url';
6+
7+
if(process.argv[2]!=='child'){
8+
constfilename=fileURLToPath(import.meta.url);
9+
constcp=fork(filename,['child']);
10+
constmessage='Hello World';
11+
cp.send(message);
12+
13+
const[received]=awaitonce(cp,'message');
14+
assert.deepStrictEqual(received,message);
15+
16+
cp.disconnect();
17+
awaitonce(cp,'exit');
18+
}else{
19+
process.on('message',(msg)=>process.send(msg));
20+
}

0 commit comments

Comments
 (0)