Skip to content

Commit 8cce4db

Browse files
authored
Fix keepRuntimeAlive in the case where EXIT_RUNTIME=0 and noExitRuntime is not referenced (#22542)
Essentially the `keepRuntimeAlive` was relying on the `noExitRuntime` variable being set based on `EXIT_RUNTIME` but when `noExitRuntime` was absent the `EXIT_RUNTIME` settings was being ignored and the runtime was exiting even though `EXIT_RUNTIME=0` was set (the default). Fixes: #20636
1 parent 4cb7739 commit 8cce4db

6 files changed

+48
-5
lines changed

src/library.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2136,10 +2136,24 @@ addToLibrary({
21362136
$runtimeKeepaliveCounter__internal: true,
21372137
$runtimeKeepaliveCounter: 0,
21382138

2139-
$keepRuntimeAlive__deps: ['$runtimeKeepaliveCounter'],
21402139
#if isSymbolNeeded('$noExitRuntime')
2140+
// If the `noExitRuntime` symbol is included in the build then
2141+
// keepRuntimeAlive is always conditional since its state can change
2142+
// at runtime.
2143+
$keepRuntimeAlive__deps: ['$runtimeKeepaliveCounter'],
21412144
$keepRuntimeAlive: () => noExitRuntime || runtimeKeepaliveCounter > 0,
2145+
#elif !EXIT_RUNTIME
2146+
// When `noExitRuntime` is not include and EXIT_RUNTIME=0 then we know the
2147+
// runtime can never exit (i.e. should always be kept alive).
2148+
// However for pthreads we always default to allowing the runtime to exit
2149+
// otherwise threads never exit and are not joinable.
2150+
#if PTHREADS
2151+
$keepRuntimeAlive: () => !ENVIRONMENT_IS_PTHREAD,
21422152
#else
2153+
$keepRuntimeAlive: () => true,
2154+
#endif
2155+
#else
2156+
$keepRuntimeAlive__deps: ['$runtimeKeepaliveCounter'],
21432157
$keepRuntimeAlive: () => runtimeKeepaliveCounter > 0,
21442158
#endif
21452159

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <assert.h>
2+
#include <emscripten/emscripten.h>
3+
#include <emscripten/em_js.h>
4+
#include <stdio.h>
5+
6+
// Verify that `keepRuntimeAlive()` always returns true by default (i.e. when
7+
// EXIT_RUNTIME=0).
8+
9+
EM_JS_DEPS(deps, "$keepRuntimeAlive");
10+
11+
EM_JS(void, timeout_func, (), {
12+
console.log("timeout_func: keepRuntimeAlive() ->", keepRuntimeAlive());
13+
// once this timeout is done the node process should exit with 0
14+
});
15+
16+
int main() {
17+
int keep_alive = EM_ASM_INT({
18+
setTimeout(timeout_func);
19+
return keepRuntimeAlive();
20+
});
21+
printf("main done: %d\n", keep_alive);
22+
assert(keep_alive == 1);
23+
return 0;
24+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
main done: 1
2+
timeout_func: keepRuntimeAlive() -> true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
53834
1+
53730

test/test_other.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4997,6 +4997,9 @@ def test(cxx, no_exit, assertions, flush=0, keepalive=0, filesystem=1):
49974997
for flush in (0, 1):
49984998
test(cxx, no_exit, assertions, flush)
49994999

5000+
def test_no_exit_runtime_strict(self):
5001+
self.do_other_test('test_no_exit_runtime_strict.c', emcc_args=['-sSTRICT'])
5002+
50005003
def test_extra_opt_levels(self):
50015004
# Opt levels that we don't tend to test elsewhere
50025005
for opt in ('-Og', '-Ofast'):

tools/link.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,6 @@ def phase_linker_setup(options, state, newargs):
658658
# Add `#!` line to output JS and make it executable.
659659
options.executable = True
660660

661-
if 'noExitRuntime' in settings.INCOMING_MODULE_JS_API:
662-
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.append('$noExitRuntime')
663-
664661
if settings.OPT_LEVEL >= 1:
665662
default_setting('ASSERTIONS', 0)
666663

@@ -918,6 +915,9 @@ def phase_linker_setup(options, state, newargs):
918915
else:
919916
default_setting('INCOMING_MODULE_JS_API', [])
920917

918+
if 'noExitRuntime' in settings.INCOMING_MODULE_JS_API:
919+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.append('$noExitRuntime')
920+
921921
if not settings.MINIMAL_RUNTIME and not settings.STRICT:
922922
# Export the HEAP object by default, when not running in STRICT mode
923923
settings.EXPORTED_RUNTIME_METHODS.extend([

0 commit comments

Comments
 (0)