Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/lib/libpthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ var LibraryPThread = {
worker.onmessage = (e) => {
var d = e['data'];
var cmd = d.cmd;
#if PTHREADS_DEBUG
dbg(`main thread: received message '${cmd}' from worker. ${d}`);
#endif

// If this message is intended to a recipient that is not the main
// thread, forward it to the target thread.
Expand Down Expand Up @@ -283,6 +286,13 @@ var LibraryPThread = {
// Worker wants to postMessage() to itself to implement setImmediate()
// emulation.
worker.postMessage(d);
#if ENVIRONMENT_MAY_BE_NODE
} else if (cmd === 'uncaughtException') {
// Message handler for Node.js specific out-of-order behavior:
// https://github.com/nodejs/node/issues/59617
// A pthread sent an uncaught exception event. Re-raise it on the main thread.
worker.onerror(d.error);
#endif
} else if (cmd === 'callHandler') {
Module[d.handler](...d.args);
} else if (cmd) {
Expand All @@ -308,6 +318,13 @@ var LibraryPThread = {
if (ENVIRONMENT_IS_NODE) {
worker.on('message', (data) => worker.onmessage({ data: data }));
worker.on('error', (e) => worker.onerror(e));

#if PTHREADS_DEBUG
worker.on('exit', (code) => {
if (worker.pthread_ptr) dbg(`Worker hosting pthread ${ptrToString(worker.pthread_ptr)} has terminated with code ${code}.`);
else dbg(`Worker has terminated with code ${code}.`);
});
#endif
}
#endif

Expand Down
15 changes: 15 additions & 0 deletions src/runtime_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ if (ENVIRONMENT_IS_NODE && {{{ ENVIRONMENT_IS_WORKER_THREAD() }}}) {
self: global,
postMessage: (msg) => parentPort['postMessage'](msg),
});
// Node.js Workers do not pass postMessage()s and uncaught exception events to the parent
// thread necessarily in the same order where they were generated in sequential program order.
// See https://github.com/nodejs/node/issues/59617
// To remedy this, capture all uncaughtExceptions in the Worker, and sequentialize those over
// to the same postMessage pipe that other messages use.
process.on("uncaughtException", (err) => {
#if PTHREADS_DEBUG
dbg(`uncaughtException on worker thread: ${err.message}`);
#endif
postMessage({ cmd: 'uncaughtException', error: err });
// Also shut down the Worker to match the same semantics as if this uncaughtException
// handler was not registered.
// (n.b. this will not shut down the whole Node.js app process, but just the Worker)
process.exit(1);
});
}
#endif // (PTHREADS || WASM_WORKERS) && (ENVIRONMENT_MAY_BE_NODE && !WASM_ESM_INTEGRATION)

Expand Down
8 changes: 4 additions & 4 deletions test/code_size/test_codesize_minimal_pthreads.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7499,
"a.out.js.gz": 3721,
"a.out.js": 7649,
"a.out.js.gz": 3768,
"a.out.nodebug.wasm": 19588,
"a.out.nodebug.wasm.gz": 9025,
"total": 27087,
"total_gz": 12746,
"total": 27237,
"total_gz": 12793,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
8 changes: 4 additions & 4 deletions test/code_size/test_codesize_minimal_pthreads_memgrowth.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7926,
"a.out.js.gz": 3924,
"a.out.js": 8076,
"a.out.js.gz": 3974,
"a.out.nodebug.wasm": 19589,
"a.out.nodebug.wasm.gz": 9025,
"total": 27515,
"total_gz": 12949,
"total": 27665,
"total_gz": 12999,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
4 changes: 1 addition & 3 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from tools import shared, building, config, utils, webassembly
import common
from common import RunnerCore, path_from_root, requires_native_clang, test_file, create_file
from common import skip_if, no_windows, no_mac, is_slow_test, parameterized, parameterize
from common import skip_if, no_windows, is_slow_test, parameterized, parameterize
from common import env_modify, with_env_modify, disabled, flaky, node_pthreads, also_without_bigint
from common import read_file, read_binary, requires_v8, requires_node, requires_dev_dependency, requires_wasm2js, requires_node_canary
from common import compiler_for, crossplatform, no_4gb, no_2gb, also_with_minimal_runtime, also_with_modularize
Expand Down Expand Up @@ -2669,8 +2669,6 @@ def test_pthread_attr_getstack(self):
self.do_run_in_out_file_test('pthread/test_pthread_attr_getstack.c')

@node_pthreads
@no_mac('https://github.com/emscripten-core/emscripten/issues/15014')
@flaky('https://github.com/emscripten-core/emscripten/issues/15014')
def test_pthread_abort(self):
self.set_setting('PROXY_TO_PTHREAD')
# Add the onAbort handler at runtime during preRun. This means that onAbort
Expand Down