@@ -648,6 +648,32 @@ void MessagePortData::AddToIncomingQueue(std::shared_ptr<Message> message) {
648648 }
649649}
650650
651+ void MessagePortData::AddWorkerExitNotification (uint64_t thread_id,
652+ ExitCode exit_code) {
653+ Mutex::ScopedLock lock (mutex_);
654+ worker_exit_notifications_.emplace_back (WorkerExitNotification{
655+ thread_id,
656+ exit_code,
657+ });
658+
659+ if (owner_ != nullptr ) {
660+ Debug (owner_, " Adding worker-exit notification" );
661+ owner_->TriggerAsync ();
662+ }
663+ }
664+
665+ bool MessagePortData::GetWorkerExitNotification (
666+ WorkerExitNotification* notification) {
667+ Mutex::ScopedLock lock (mutex_);
668+
669+ if (worker_exit_notifications_.empty ()) return false ;
670+
671+ *notification = worker_exit_notifications_.front ();
672+ worker_exit_notifications_.pop_front ();
673+
674+ return true ;
675+ }
676+
651677void MessagePortData::Entangle (MessagePortData* a, MessagePortData* b) {
652678 auto group = std::make_shared<SiblingGroup>();
653679 group->Entangle ({a, b});
@@ -823,6 +849,7 @@ void MessagePort::OnMessage(MessageProcessingMode mode) {
823849 HandleScope handle_scope (env ()->isolate ());
824850 Local<Context> context =
825851 object (env ()->isolate ())->GetCreationContextChecked ();
852+ Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
826853
827854 size_t processing_limit;
828855 if (mode == MessageProcessingMode::kNormalOperation ) {
@@ -850,9 +877,43 @@ void MessagePort::OnMessage(MessageProcessingMode mode) {
850877 return ;
851878 }
852879
880+ MessagePortData::WorkerExitNotification worker_exit;
881+
882+ if (data_->GetWorkerExitNotification (&worker_exit)) {
883+ Debug (this ,
884+ " Worker exited: thread_id=%" PRIu64 " , exit_code=%d" ,
885+ worker_exit.thread_id ,
886+ static_cast <int >(worker_exit.exit_code ));
887+
888+ Local<Object> exit_info = Object::New (env ()->isolate ());
889+
890+ exit_info
891+ ->Set (context,
892+ FIXED_ONE_BYTE_STRING (env ()->isolate (), " threadId" ),
893+ v8::Number::New (env ()->isolate (), worker_exit.thread_id ))
894+ .Check ();
895+
896+ exit_info
897+ ->Set (context,
898+ FIXED_ONE_BYTE_STRING (env ()->isolate (), " exitCode" ),
899+ v8::Integer::New (env ()->isolate (),
900+ static_cast <int >(worker_exit.exit_code )))
901+ .Check ();
902+
903+ Local<Value> argv[3 ];
904+ argv[0 ] = exit_info;
905+ argv[1 ] = Undefined (env ()->isolate ());
906+ argv[2 ] = FIXED_ONE_BYTE_STRING (env ()->isolate (), " workerexited" );
907+
908+ if (MakeCallback (emit_message, arraysize (argv), argv).IsEmpty ()) {
909+ if (data_) TriggerAsync ();
910+ return ;
911+ }
912+ continue ;
913+ }
914+
853915 HandleScope handle_scope (env ()->isolate ());
854916 Context::Scope context_scope (context);
855- Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
856917
857918 Local<Value> payload;
858919 Local<Value> port_list = Undefined (env ()->isolate ());
@@ -901,6 +962,20 @@ void MessagePort::OnMessage(MessageProcessingMode mode) {
901962void MessagePort::OnClose () {
902963 Debug (this , " MessagePort::OnClose()" );
903964 if (data_) {
965+ Environment* environment = env ();
966+ if (environment->is_stopping ()) {
967+ const uint64_t thread_id = environment->thread_id ();
968+ const ExitCode exit_code = environment->exit_code (ExitCode::kNoFailure );
969+
970+ Debug (this ,
971+ " Worker exiting: thread_id=%" PRIu64 " , exit_code=%d" ,
972+ thread_id,
973+ static_cast <int >(exit_code));
974+
975+ if (data_->group_ ) {
976+ data_->group_ ->NotifyWorkerExit (data_.get (), thread_id, exit_code);
977+ }
978+ }
904979 // Detach() returns move(data_).
905980 Detach ()->Disentangle ();
906981 }
@@ -1587,6 +1662,18 @@ void SiblingGroup::Disentangle(MessagePortData* data) {
15871662 (*(ports_.begin ()))->AddToIncomingQueue (std::make_shared<Message>());
15881663}
15891664
1665+ void SiblingGroup::NotifyWorkerExit (MessagePortData* exiting_port,
1666+ uint64_t thread_id,
1667+ ExitCode exit_code) {
1668+ RwLock::ScopedReadLock lock (group_mutex_);
1669+
1670+ for (MessagePortData* port : ports_) {
1671+ if (port == exiting_port) continue ;
1672+
1673+ port->AddWorkerExitNotification (thread_id, exit_code);
1674+ }
1675+ }
1676+
15901677SiblingGroup::Map SiblingGroup::groups_;
15911678Mutex SiblingGroup::groups_mutex_;
15921679
0 commit comments