Skip to content

Commit 8d9ef56

Browse files
committed
Add emscripten_queue_microtask
This change adds a new `emscripten_queue_microtask` API to match the long standing web API (also available in node). See https://developer.mozilla.org/en-US/docs/Web/API/Window/queueMicrotask For now, I'm adding this without a polyfill so usage of the API will crash on very old targets. We could potentially polyfill using something like setTimeout, but the semantics are a little different so I'm not sure it worth doing. Split out from emscripten-core#24481
1 parent 45c5002 commit 8d9ef56

File tree

6 files changed

+44
-0
lines changed

6 files changed

+44
-0
lines changed

src/lib/libeventloop.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ LibraryJSEventLoop = {
8585
$emClearImmediate_deps: ['$emSetImmediate'],
8686
$emClearImmediate: undefined,
8787

88+
emscripten_queue_microtask__deps: ['$emSetImmediate', '$callUserCallback'],
89+
emscripten_queue_microtask: (cb, userData) => {
90+
{{{ runtimeKeepalivePush(); }}}
91+
return queueMicrotask(() => {
92+
{{{ runtimeKeepalivePop(); }}}
93+
callUserCallback(() => {{{ makeDynCall('vp', 'cb') }}}(userData));
94+
});
95+
},
96+
8897
emscripten_set_immediate__deps: ['$emSetImmediate', '$callUserCallback'],
8998
emscripten_set_immediate: (cb, userData) => {
9099
{{{ runtimeKeepalivePush(); }}}

src/lib/libsigs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ sigs = {
733733
emscripten_promise_race__sig: 'ppp',
734734
emscripten_promise_resolve__sig: 'vpip',
735735
emscripten_promise_then__sig: 'ppppp',
736+
emscripten_queue_microtask__sig: 'ipp',
736737
emscripten_random__sig: 'f',
737738
emscripten_request_animation_frame__sig: 'ipp',
738739
emscripten_request_animation_frame_loop__sig: 'vpp',

system/include/emscripten/eventloop.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ void emscripten_set_immediate_loop(bool (*cb)(void *user_data), void *user_data)
2626
int emscripten_set_interval(void (*cb)(void *user_data) __attribute__((nonnull)), double interval_ms, void *user_data);
2727
void emscripten_clear_interval(int id);
2828

29+
int emscripten_queue_microtask(void (*cb)(void *user_data) __attribute__((nonnull)), void *user_data);
30+
2931
void emscripten_runtime_keepalive_push(void);
3032
void emscripten_runtime_keepalive_pop(void);
3133
bool emscripten_runtime_keepalive_check(void);

test/other/test_queue_microtask.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <assert.h>
2+
#include <stdbool.h>
3+
#include <stdio.h>
4+
#include <emscripten/eventloop.h>
5+
6+
bool got_timeout = false;
7+
bool got_microtask = false;
8+
9+
void callback_timeout(void* user_data) {
10+
assert(got_microtask);
11+
printf("callback_timeout: %ld\n", (intptr_t)user_data);
12+
got_timeout = true;
13+
}
14+
15+
void callback_microtask(void* user_data) {
16+
assert(!got_timeout);
17+
printf("callback_microtask: %ld\n", (intptr_t)user_data);
18+
got_microtask = true;
19+
}
20+
21+
int main() {
22+
emscripten_set_timeout(callback_timeout, 0, (void*)42);
23+
emscripten_queue_microtask(callback_microtask, (void*)43);
24+
printf("done main\n");
25+
return 0;
26+
}

test/other/test_queue_microtask.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
done main
2+
callback_microtask: 43
3+
callback_timeout: 42

test/test_other.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16186,3 +16186,6 @@ def test_unsupported_min_version_when_unsupported_env(self, env):
1618616186
self.assertContainedIf(f'var MIN_CHROME_VERSION = {unsupported};', src, env == 'node')
1618716187
self.assertContainedIf(f'var MIN_SAFARI_VERSION = {unsupported};', src, env == 'node')
1618816188
self.assertContainedIf(f'var MIN_FIREFOX_VERSION = {unsupported};', src, env == 'node')
16189+
16190+
def test_queue_microtask(self):
16191+
self.do_other_test('test_queue_microtask.c')

0 commit comments

Comments
 (0)