Skip to content

Commit c1a2f16

Browse files
committed
Decrelment keepalive counter in emscripten_clear_timeout
This change also cleans up the emscripten tests relating to the event loop. The browser tests were only being run in `PROXY_TO_PTHREAD` mode for some reason even though these tests should pass on the main thread. In test_other the `PROXY_TO_PTHREAD` flags were being passed as args (rather then emcc_args). Likely a copy/paste bug.
1 parent 88f9144 commit c1a2f16

14 files changed

+81
-83
lines changed

src/lib/libeventloop.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ LibraryJSEventLoop = {
2121
}, timeout);
2222
},
2323

24+
$safeClearTimeout: (id) => {
25+
// TODO: Track outstanding timeout IDs so that we can avoid calling
26+
// runtimeKeepalivePop trice for the same timeout.
27+
{{{ runtimeKeepalivePop() }}}
28+
clearTimeout(id);
29+
},
30+
2431
// Just like setImmediate but returns an i32 that can be passed back
2532
// to wasm rather than a JS object.
2633
$setImmediateWrapped: (func) => {
@@ -119,13 +126,7 @@ LibraryJSEventLoop = {
119126
emscripten_set_timeout: (cb, msecs, userData) =>
120127
safeSetTimeout(() => {{{ makeDynCall('vp', 'cb') }}}(userData), msecs),
121128

122-
#if AUDIO_WORKLET
123-
// Use a wrapper function here since simply aliasing `clearTimeout` would
124-
// cause the module to fail to load in the audio worklet context.
125-
emscripten_clear_timeout: (id) => clearTimeout(id),
126-
#else
127-
emscripten_clear_timeout: 'clearTimeout',
128-
#endif
129+
emscripten_clear_timeout: '$safeClearTimeout',
129130

130131
emscripten_set_timeout_loop__deps: ['$callUserCallback', 'emscripten_get_now'],
131132
emscripten_set_timeout_loop: (cb, msecs, userData) => {

src/lib/libsdl.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3579,9 +3579,10 @@ var LibrarySDL = {
35793579
() => {{{ makeDynCall('iip', 'callback') }}}(interval, param),
35803580
interval),
35813581

3582+
SDL_RemoveTimer__deps: ['$safeClearTimeout'],
35823583
SDL_RemoveTimer__proxy: 'sync',
35833584
SDL_RemoveTimer: (id) => {
3584-
clearTimeout(id);
3585+
safeClearTimeout(id);
35853586
return true;
35863587
},
35873588

test/emscripten_performance_now.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ void test(void *userData) {
1212
double now3 = emscripten_date_now();
1313
assert(now3 >= dateNow + 100);
1414

15-
#ifdef REPORT_RESULT
16-
REPORT_RESULT(0);
17-
#endif
15+
exit(0);
1816
}
1917

2018
int main() {
@@ -30,4 +28,5 @@ int main() {
3028
#else
3129
emscripten_set_timeout(test, 200, 0);
3230
#endif
31+
return 99;
3332
}

test/emscripten_set_interval.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
int funcExecuted = 0;
88

99
void testDone(void *userData) {
10+
printf("testDone\n");
1011
assert((long)userData == 2);
1112
assert(funcExecuted == 10);
1213
exit(0);
@@ -15,6 +16,7 @@ void testDone(void *userData) {
1516
long intervalId = 0;
1617

1718
void tick(void *userData) {
19+
printf("tick: %d\n", funcExecuted);
1820
assert((long)userData == 1);
1921
++funcExecuted;
2022
if (funcExecuted == 10) {
@@ -28,6 +30,5 @@ void tick(void *userData) {
2830

2931
int main() {
3032
intervalId = emscripten_set_interval(tick, 100, (void*)1);
31-
emscripten_exit_with_live_runtime();
3233
return 99;
3334
}

test/emscripten_set_timeout.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
#include <emscripten/emscripten.h>
22
#include <emscripten/html5.h>
3-
#include <emscripten/em_asm.h>
43
#include <assert.h>
54
#include <stdlib.h>
5+
#include <stdio.h>
66

77
int func1Executed = 0;
88
int func2Executed = 0;
99

1010
void func1(void *userData);
1111

1212
void func2(void *userData) {
13+
printf("func2: %d\n", func2Executed);
1314
assert((long)userData == 2);
1415
++func2Executed;
1516

16-
if (func2Executed == 1)
17-
{
17+
if (func2Executed == 1) {
1818
// Test canceling a setTimeout: register a callback but then cancel it immediately
1919
long id = emscripten_set_timeout(func1, 10, (void*)2);
2020
emscripten_clear_timeout(id);
2121

2222
emscripten_set_timeout(func2, 100, (void*)2);
2323
}
24-
if (func2Executed == 2)
25-
{
24+
25+
if (func2Executed == 2) {
2626
assert(func1Executed == 1);
2727
exit(0);
2828
}
2929
}
3030

3131
void func1(void *userData) {
32+
printf("func1\n");
3233
assert((long)userData == 1);
3334
++func1Executed;
3435

@@ -39,6 +40,5 @@ void func1(void *userData) {
3940

4041
int main() {
4142
emscripten_set_timeout(func1, 100, (void*)1);
42-
emscripten_exit_with_live_runtime();
4343
return 99;
4444
}

test/emscripten_set_timeout_loop.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,34 @@
11
#include <emscripten/emscripten.h>
22
#include <emscripten/html5.h>
3-
#include <emscripten/em_asm.h>
43
#include <assert.h>
54
#include <stdlib.h>
5+
#include <stdio.h>
66

77
double previousSetTimeouTime = 0;
88
int funcExecuted = 0;
99

1010
void testDone(void *userData) {
11+
printf("testDone\n");
1112
assert((long)userData == 2);
1213
assert(funcExecuted == 10);
14+
emscripten_runtime_keepalive_pop();
1315
exit(0);
1416
}
1517

1618
bool tick(double time, void *userData) {
19+
printf("tick: %d\n", funcExecuted);
1720
assert(time >= previousSetTimeouTime);
1821
previousSetTimeouTime = time;
1922
assert((long)userData == 1);
2023
++funcExecuted;
21-
if (funcExecuted == 10)
22-
{
24+
if (funcExecuted == 10) {
2325
emscripten_set_timeout(testDone, 300, (void*)2);
2426
}
2527
return funcExecuted < 10;
2628
}
2729

2830
int main() {
2931
emscripten_set_timeout_loop(tick, 100, (void*)1);
30-
emscripten_exit_with_live_runtime();
32+
emscripten_runtime_keepalive_push();
3133
return 99;
3234
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7984
1+
7989
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
21327
1+
21344
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6330
1+
6336
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
16673
1+
16690
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
52478
1+
52500
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
50766
1+
50788

test/test_browser.py

+46-49
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,22 @@ def decorated(self, threads, *args, **kwargs):
200200
f(self, *args, **kwargs)
201201

202202
parameterize(decorated, {'': (False,),
203-
'pthreads': (True,)})
203+
'pthread': (True,)})
204+
205+
return decorated
206+
207+
208+
def also_with_proxy_to_pthread(f):
209+
assert callable(f)
210+
211+
@wraps(f)
212+
def decorated(self, threads, *args, **kwargs):
213+
if threads:
214+
self.emcc_args += ['-pthread', '-sPROXY_TO_PTHREAD']
215+
f(self, *args, **kwargs)
216+
217+
parameterize(decorated, {'': (False,),
218+
'pthread': (True,)})
204219

205220
return decorated
206221

@@ -496,14 +511,11 @@ def make_main_two_files(path1, path2, nonexistingpath):
496511
self.btest_exit('main.c', args=['--pre-js', 'pre.js', '--use-preload-plugins'])
497512

498513
# Tests that user .html shell files can manually download .data files created with --preload-file cmdline.
499-
@parameterized({
500-
'': ([],),
501-
'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD', '-sEXIT_RUNTIME'],),
502-
})
503-
def test_preload_file_with_manual_data_download(self, args):
514+
@also_with_proxy_to_pthread
515+
def test_preload_file_with_manual_data_download(self):
504516
create_file('file.txt', 'Hello!')
505517

506-
self.compile_btest('browser/test_manual_download_data.c', ['-sEXIT_RUNTIME', '-o', 'out.js', '--preload-file', 'file.txt@/file.txt'] + args)
518+
self.compile_btest('browser/test_manual_download_data.c', ['-sEXIT_RUNTIME', '-o', 'out.js', '--preload-file', 'file.txt@/file.txt'])
507519
shutil.copy(test_file('browser/test_manual_download_data.html'), '.')
508520

509521
# Move .data file out of server root to ensure that getPreloadedPackage is actually used
@@ -1603,12 +1615,9 @@ def test_glfw_time(self):
16031615
def test_egl(self, args):
16041616
self.btest_exit('test_egl.c', args=['-O2', '-lEGL', '-lGL', '-sGL_ENABLE_GET_PROC_ADDRESS'] + args)
16051617

1606-
@parameterized({
1607-
'': ([],),
1608-
'proxy_to_pthread': (['-pthread', '-sPROXY_TO_PTHREAD'],),
1609-
})
1610-
def test_egl_width_height(self, args):
1611-
self.btest_exit('test_egl_width_height.c', args=['-O2', '-lEGL', '-lGL'] + args)
1618+
@also_with_proxy_to_pthread
1619+
def test_egl_width_height(self):
1620+
self.btest_exit('test_egl_width_height.c', args=['-O2', '-lEGL', '-lGL'])
16121621

16131622
@requires_graphics_hardware
16141623
def test_egl_createcontext_error(self):
@@ -1901,27 +1910,17 @@ def test_emscripten_fs_api2(self):
19011910
self.btest_exit('emscripten_fs_api_browser2.c', args=['-sASSERTIONS=0'])
19021911
self.btest_exit('emscripten_fs_api_browser2.c', args=['-sASSERTIONS=1'])
19031912

1904-
@parameterized({
1905-
'': ([],),
1906-
'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD', '-sEXIT_RUNTIME'],),
1907-
})
1908-
def test_emscripten_main_loop(self, args):
1909-
self.btest_exit('test_emscripten_main_loop.c', args=args)
1913+
@also_with_proxy_to_pthread
1914+
def test_emscripten_main_loop(self):
1915+
self.btest_exit('test_emscripten_main_loop.c')
19101916

1911-
@parameterized({
1912-
'': ([],),
1913-
# test pthreads + AUTO_JS_LIBRARIES mode as well
1914-
'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD', '-sAUTO_JS_LIBRARIES=0'],),
1915-
})
1916-
def test_emscripten_main_loop_settimeout(self, args):
1917-
self.btest_exit('test_emscripten_main_loop_settimeout.c', args=args)
1917+
@also_with_proxy_to_pthread
1918+
def test_emscripten_main_loop_settimeout(self):
1919+
self.btest_exit('test_emscripten_main_loop_settimeout.c', args=['-sAUTO_JS_LIBRARIES=0'])
19181920

1919-
@parameterized({
1920-
'': ([],),
1921-
'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD'],),
1922-
})
1923-
def test_emscripten_main_loop_and_blocker(self, args):
1924-
self.btest_exit('test_emscripten_main_loop_and_blocker.c', args=args)
1921+
@also_with_proxy_to_pthread
1922+
def test_emscripten_main_loop_and_blocker(self):
1923+
self.btest_exit('test_emscripten_main_loop_and_blocker.c')
19251924

19261925
def test_emscripten_main_loop_and_blocker_exit(self):
19271926
# Same as above but tests that EXIT_RUNTIME works with emscripten_main_loop. The
@@ -1977,13 +1976,10 @@ def test_sdl_glshader2(self):
19771976
def test_gl_glteximage(self):
19781977
self.btest('gl_teximage.c', '1', args=['-lGL', '-lSDL'])
19791978

1980-
@parameterized({
1981-
'': ([],),
1982-
'pthreads': (['-pthread', '-sPROXY_TO_PTHREAD', '-sOFFSCREEN_FRAMEBUFFER'],),
1983-
})
19841979
@requires_graphics_hardware
1985-
def test_gl_textures(self, args):
1986-
self.btest_exit('gl_textures.c', args=['-lGL', '-g', '-sSTACK_SIZE=1MB'] + args)
1980+
@also_with_proxy_to_pthread
1981+
def test_gl_textures(self):
1982+
self.btest_exit('gl_textures.c', args=['-lGL', '-g', '-sSTACK_SIZE=1MB', '-sOFFSCREEN_FRAMEBUFFER'])
19871983

19881984
@requires_graphics_hardware
19891985
def test_gl_ps(self):
@@ -2618,10 +2614,10 @@ def test_html5_core(self, opts):
26182614
self.emcc_args.append('--pre-js=pre.js')
26192615
self.btest_exit('test_html5_core.c', args=opts)
26202616

2617+
@also_with_proxy_to_pthread
26212618
@parameterized({
26222619
'': ([],),
26232620
'closure': (['-O2', '-g1', '--closure=1'],),
2624-
'pthread': (['-pthread', '-sPROXY_TO_PTHREAD'],),
26252621
})
26262622
def test_html5_gamepad(self, args):
26272623
self.btest_exit('test_gamepad.c', args=args)
@@ -4932,24 +4928,28 @@ def test_emscripten_request_animation_frame_loop(self):
49324928
def test_request_animation_frame(self):
49334929
self.btest_exit('test_request_animation_frame.c')
49344930

4931+
@also_with_proxy_to_pthread
49354932
def test_emscripten_set_timeout(self):
4936-
self.btest_exit('emscripten_set_timeout.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
4933+
self.btest_exit('emscripten_set_timeout.c')
49374934

4935+
@also_with_proxy_to_pthread
49384936
def test_emscripten_set_timeout_loop(self):
4939-
self.btest_exit('emscripten_set_timeout_loop.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
4937+
self.btest_exit('emscripten_set_timeout_loop.c')
49404938

49414939
def test_emscripten_set_immediate(self):
49424940
self.btest_exit('emscripten_set_immediate.c')
49434941

49444942
def test_emscripten_set_immediate_loop(self):
49454943
self.btest_exit('emscripten_set_immediate_loop.c')
49464944

4945+
@also_with_proxy_to_pthread
49474946
def test_emscripten_set_interval(self):
4948-
self.btest_exit('emscripten_set_interval.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
4947+
self.btest_exit('emscripten_set_interval.c')
49494948

49504949
# Test emscripten_performance_now() and emscripten_date_now()
4950+
@also_with_proxy_to_pthread
49514951
def test_emscripten_performance_now(self):
4952-
self.btest('emscripten_performance_now.c', '0', args=['-pthread', '-sPROXY_TO_PTHREAD'])
4952+
self.btest_exit('emscripten_performance_now.c')
49534953

49544954
def test_embind_with_pthreads(self):
49554955
self.btest_exit('embind/test_pthreads.cpp', args=['-lembind', '-pthread', '-sPTHREAD_POOL_SIZE=2'])
@@ -5021,12 +5021,9 @@ def test_minimal_runtime_loader_shell(self, args):
50215021
def test_minimal_runtime_hello_world(self, args):
50225022
self.btest_exit('small_hello_world.c', args=args + ['-sMINIMAL_RUNTIME'])
50235023

5024-
@parameterized({
5025-
'': ([],),
5026-
'pthread': (['-sPROXY_TO_PTHREAD', '-pthread'],)
5027-
})
5028-
def test_offset_converter(self, args):
5029-
self.btest_exit('test_offset_converter.c', args=['-sUSE_OFFSET_CONVERTER', '-gsource-map'] + args)
5024+
@also_with_proxy_to_pthread
5025+
def test_offset_converter(self):
5026+
self.btest_exit('test_offset_converter.c', args=['-sUSE_OFFSET_CONVERTER', '-gsource-map'])
50305027

50315028
# Tests emscripten_unwind_to_js_event_loop() behavior
50325029
def test_emscripten_unwind_to_js_event_loop(self):

test/test_other.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -13883,9 +13883,8 @@ def test_pthread_trap(self):
1388313883
def test_pthread_kill(self):
1388413884
self.do_run_in_out_file_test('pthread/test_pthread_kill.c')
1388513885

13886-
@node_pthreads
1388713886
def test_emscripten_set_interval(self):
13888-
self.do_runf('emscripten_set_interval.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
13887+
self.do_runf('emscripten_set_interval.c')
1388913888

1389013889
# Test emscripten_console_log(), emscripten_console_warn() and emscripten_console_error()
1389113890
def test_emscripten_console_log(self):
@@ -13895,13 +13894,11 @@ def test_emscripten_console_log(self):
1389513894
def test_emscripten_unwind_to_js_event_loop(self):
1389613895
self.do_runf('test_emscripten_unwind_to_js_event_loop.c')
1389713896

13898-
@node_pthreads
1389913897
def test_emscripten_set_timeout(self):
13900-
self.do_runf('emscripten_set_timeout.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
13898+
self.do_runf('emscripten_set_timeout.c')
1390113899

13902-
@node_pthreads
1390313900
def test_emscripten_set_timeout_loop(self):
13904-
self.do_runf('emscripten_set_timeout_loop.c', args=['-pthread', '-sPROXY_TO_PTHREAD'])
13901+
self.do_runf('emscripten_set_timeout_loop.c')
1390513902

1390613903
# Verify that we are able to successfully compile a script when the Windows 7
1390713904
# and Python workaround env. vars are enabled.

0 commit comments

Comments
 (0)