11
11
#include <emscripten/proxying.h>
12
12
#include <emscripten/threading.h>
13
13
14
- bool should_quit = false;
15
- pthread_t looper ;
16
-
17
14
// In the actual implementation of malloc the system queue may be executed
18
15
// non-deterministically if malloc is waiting on a mutex. This wraps malloc and
19
16
// executes the system queue during every allocation to make the behavior
@@ -26,22 +23,18 @@ void *malloc(size_t size) {
26
23
return ptr ;
27
24
}
28
25
29
- void run_on_looper (void * arg ) {
30
- emscripten_out ("run_on_looper\n" );
31
- should_quit = true;
32
- }
33
-
34
- void * looper_main (void * arg ) {
35
- while (!should_quit ) {
36
- emscripten_proxy_execute_queue (emscripten_proxy_get_system_queue ());
37
- sched_yield ();
38
- }
39
- return NULL ;
26
+ void task (void * arg ) {
27
+ emscripten_out ("task\n" );
40
28
}
41
29
42
30
int main () {
43
- pthread_create (& looper , NULL , looper_main , NULL );
44
- emscripten_proxy_async (emscripten_proxy_get_system_queue (), looper , run_on_looper , NULL );
45
- pthread_join (looper , NULL );
31
+ // Tests for a deadlock scenario that can occur when sending a task.
32
+ // The sequence of events is:
33
+ // 1. Sending a task locks the queue.
34
+ // 2. Allocating a new task queue calls malloc.
35
+ // 3. Malloc then attempts to execute and lock the already-locked queue,
36
+ // causing a deadlock.
37
+ // This test ensures our implementation prevents this re-entrant lock.
38
+ emscripten_proxy_async (emscripten_proxy_get_system_queue (), pthread_self (), task , NULL );
46
39
emscripten_out ("done\n" );
47
40
}
0 commit comments