Skip to content

Commit 765ce7f

Browse files
authored
Decrement proxying queue refcounts in finally blocks (#16571)
This ensures that the refcounts are correctly decremented even if a proxied task throws an exception, although it won't protect again other bad things like dropped work that could happen in that case.
1 parent ce0ed66 commit 765ce7f

File tree

2 files changed

+19
-20
lines changed

2 files changed

+19
-20
lines changed

src/library_pthread.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,7 @@ var LibraryPThread = {
268268
}
269269

270270
if (cmd === 'processProxyingQueue') {
271-
// TODO: Must post message to main Emscripten thread in PROXY_TO_WORKER mode.
272-
_emscripten_proxy_execute_queue(d['queue']);
273-
// Decrement the ref count
274-
Atomics.sub(HEAP32, d['queue'] >> 2, 1);
271+
executeNotifiedProxyingQueue(d['queue']);
275272
} else if (cmd === 'spawnThread') {
276273
spawnThread(d);
277274
} else if (cmd === 'cleanupThread') {
@@ -1047,19 +1044,25 @@ var LibraryPThread = {
10471044
return {{{ makeDynCall('ii', 'ptr') }}}(arg);
10481045
},
10491046

1047+
$executeNotifiedProxyingQueue: function(queue) {
1048+
try {
1049+
// Only execute the queue if we have a live pthread runtime. We
1050+
// implement pthread_self to return 0 if there is no live runtime.
1051+
// TODO: Use `callUserCallback` to correctly handle unwinds, etc. once
1052+
// `runtimeExited` is correctly unset on workers.
1053+
if (_pthread_self()) {
1054+
_emscripten_proxy_execute_queue(queue);
1055+
}
1056+
} finally {
1057+
// Always decrement the ref count.
1058+
Atomics.sub(HEAP32, queue >> 2, 1);
1059+
}
1060+
},
1061+
1062+
_emscripten_notify_proxying_queue__deps: ['$executeNotifiedProxyingQueue'],
10501063
_emscripten_notify_proxying_queue: function(targetThreadId, currThreadId, mainThreadId, queue) {
10511064
if (targetThreadId == currThreadId) {
1052-
setTimeout(() => {
1053-
// Only execute the queue if we have a live pthread runtime. We
1054-
// implement pthread_self to return 0 if there is no live runtime.
1055-
// TODO: Use `callUserCallback` to correctly handle unwinds, etc. once
1056-
// `runtimeExited` is correctly unset on workers.
1057-
if (_pthread_self()) {
1058-
_emscripten_proxy_execute_queue(queue);
1059-
}
1060-
// Decrement the ref count
1061-
Atomics.sub(HEAP32, queue >> 2, 1);
1062-
});
1065+
setTimeout(() => executeNotifiedProxyingQueue(queue));
10631066
} else if (ENVIRONMENT_IS_PTHREAD) {
10641067
postMessage({'targetThread' : targetThreadId, 'cmd' : 'processProxyingQueue', 'queue' : queue});
10651068
} else {

src/worker.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,7 @@ self.onmessage = (e) => {
286286
} else if (e.data.target === 'setimmediate') {
287287
// no-op
288288
} else if (e.data.cmd === 'processProxyingQueue') {
289-
if (Module['_pthread_self']()) { // If this thread is actually running?
290-
Module['_emscripten_proxy_execute_queue'](e.data.queue);
291-
}
292-
// Decrement the ref count
293-
Atomics.sub(HEAP32, e.data.queue >> 2, 1);
289+
executeNotifiedProxyingQueue(e.data.queue);
294290
} else {
295291
err('worker.js received unknown command ' + e.data.cmd);
296292
err(e.data);

0 commit comments

Comments
 (0)