Skip to content

Commit 7c24ee8

Browse files
committed
add test
1 parent 9528e48 commit 7c24ee8

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Emscripten Authors. All rights reserved.
2+
// Emscripten is available under two separate licenses, the MIT license and the
3+
// University of Illinois/NCSA Open Source License. Both these licenses can be
4+
// found in the LICENSE file.
5+
6+
#include <pthread.h>
7+
#include <stdlib.h>
8+
#include <unistd.h>
9+
#include <emscripten/console.h>
10+
#include <emscripten/heap.h>
11+
#include <emscripten/proxying.h>
12+
#include <emscripten/threading.h>
13+
14+
bool should_quit = false;
15+
pthread_t looper;
16+
17+
// In the actual implementation of malloc the system queue may be executed
18+
// non-deterministically if malloc is waiting on a mutex. This wraps malloc and
19+
// executes the system queue during every allocation to make the behavior
20+
// deterministic.
21+
void *malloc(size_t size) {
22+
if (emscripten_proxy_get_system_queue() && emscripten_is_main_runtime_thread()) {
23+
emscripten_proxy_execute_queue(emscripten_proxy_get_system_queue());
24+
}
25+
void *ptr = emscripten_builtin_malloc(size);
26+
return ptr;
27+
}
28+
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;
40+
}
41+
42+
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);
46+
emscripten_out("done\n");
47+
}

test/test_core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,6 +2564,10 @@ def test_pthread_cancel(self):
25642564
def test_pthread_cancel_async(self):
25652565
self.do_run_in_out_file_test('pthread/test_pthread_cancel_async.c')
25662566

2567+
@node_pthreads
2568+
def test_pthread_proxy_deadlock(self):
2569+
self.do_runf('pthread/test_pthread_proxy_deadlock.c')
2570+
25672571
@no_asan('test relies on null pointer reads')
25682572
def test_pthread_specific(self):
25692573
self.do_run_in_out_file_test('pthread/specific.c')

0 commit comments

Comments
 (0)