Skip to content

Commit

Permalink
Handle thread crash/abort even when main thread is blocking (busy-wai…
Browse files Browse the repository at this point in the history
…ting). NFC

Previously if a thread crashed when the main thread was blocked on
something (such as pthread_join) it would never get the `onerror`
message because it would never return the event loop.
  • Loading branch information
sbc100 committed Feb 2, 2022
1 parent e002f7f commit f4dc6e8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,7 @@ def default_setting(name, new_default):
worker_imports = [
'__emscripten_thread_init',
'__emscripten_thread_exit',
'__emscripten_thread_crashed',
'_emscripten_tls_init',
'_emscripten_current_thread_process_queued_calls',
'_pthread_self',
Expand Down
3 changes: 3 additions & 0 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ self.onmessage = (e) => {
err(e.data);
}
} catch(ex) {
if (Module['__emscripten_thread_crashed']) {
Module['__emscripten_thread_crashed']();
}
err('worker.js onmessage() captured an uncaught exception: ' + ex);
if (ex && ex.stack) err(ex.stack);
throw ex;
Expand Down
15 changes: 15 additions & 0 deletions system/lib/pthread/emscripten_futex_wait.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <errno.h>
#include <math.h>
#include <emscripten/threading.h>
#include <stdbool.h>
#include <stdlib.h>
#include "atomic.h"
#include "threading_internal.h"

Expand Down Expand Up @@ -106,11 +108,24 @@ static int futex_wait_busy(volatile void *addr, uint32_t val, double timeout) {
return 0;
}

static _Atomic bool thread_crashed = false;

void _emscripten_thread_crashed() {
thread_crashed = true;
}

int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms) {
if ((((intptr_t)addr)&3) != 0) {
return -EINVAL;
}

// When a secondary thread crashes we need to be able to inturrupt the main
// thread is its in a busy loop. We can't use the normal proxying mechanism
// since it could allocate or itself crash so use a low level atomic primitive
// for this signal.
if (emscripten_is_main_runtime_thread() && thread_crashed)
abort();

int ret;
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITFUTEX);

Expand Down

0 comments on commit f4dc6e8

Please sign in to comment.