Skip to content

Commit 3641a56

Browse files
edusperoniNathanWalker
authored andcommitted
fix(runtime): shim removeListener drops the newest registration; an adopted port is recorded before the list write can fail
WorkerEmitter.removeListener scanned forwards while ParentPort and Node remove the most recently added registration. In Deserialize a port adopted successfully but not yet recorded was skipped by the failure cleanup when the ports array write failed, leaving it registered with no handle.
1 parent d13571d commit 3641a56

2 files changed

Lines changed: 10 additions & 4 deletions

File tree

‎NativeScript/runtime/StructuredSerialization.cpp‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -685,13 +685,18 @@ MaybeLocal<Value> SerializedValue::Deserialize(Isolate* isolate,
685685
for (size_t i = 0; i < transferredPorts_.size(); i++) {
686686
Local<Object> wrapper;
687687
if (!messaging::AdoptPort(context, std::move(transferredPorts_[i]))
688-
.ToLocal(&wrapper) ||
689-
!list->Set(context, static_cast<uint32_t>(i), wrapper)
690-
.FromMaybe(false)) {
688+
.ToLocal(&wrapper)) {
691689
CloseUnreachablePorts(isolate, ports, nullptr);
692690
return MaybeLocal<Value>();
693691
}
692+
// Recorded before anything else can fail: an adopted port that is not
693+
// in this list would never be closed.
694694
ports.push_back(wrapper);
695+
if (!list->Set(context, static_cast<uint32_t>(i), wrapper)
696+
.FromMaybe(false)) {
697+
CloseUnreachablePorts(isolate, ports, nullptr);
698+
return MaybeLocal<Value>();
699+
}
695700
}
696701
if (portList != nullptr) {
697702
*portList = list;

‎NativeScript/runtime/js/node-worker-threads.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ class WorkerEmitter {
104104
return this;
105105
}
106106

107+
// Node removes the most recently added registration of a listener.
107108
removeListener(type, listener) {
108109
const list = this.#listeners[`${type}`];
109110
if (list === undefined) {
110111
return this;
111112
}
112-
for (let i = 0; i < list.length; i++) {
113+
for (let i = list.length - 1; i >= 0; i--) {
113114
if (list[i].listener === listener) {
114115
ArrayPrototypeSplice(list, i, 1);
115116
return this;

0 commit comments

Comments
 (0)