Skip to content

Commit 187c744

Browse files
committed
Enable longjmp + pthreads + dylink
The underlying bug that caused this configuration not to work (lack of TLS import/export) was fixed in #14971. Fixes: #14461
1 parent 051c5c1 commit 187c744

6 files changed

+55
-8
lines changed

emcc.py

-4
Original file line numberDiff line numberDiff line change
@@ -2015,10 +2015,6 @@ def include_and_export(name):
20152015
elif settings.LINKABLE:
20162016
diagnostics.warning('experimental', '-s LINKABLE + pthreads is experimental')
20172017

2018-
default_setting('SUPPORT_LONGJMP', 0)
2019-
if settings.SUPPORT_LONGJMP:
2020-
exit_with_error('SUPPORT_LONGJMP is not compatible with pthreads + dynamic linking')
2021-
20222018
if settings.PROXY_TO_WORKER:
20232019
exit_with_error('--proxy-to-worker is not supported with -s USE_PTHREADS>0! Use the option -s PROXY_TO_PTHREAD=1 if you want to run the main thread of a multithreaded application in a web worker.')
20242020
elif settings.PROXY_TO_PTHREAD:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <assert.h>
2+
#include <setjmp.h>
3+
#include <stdbool.h>
4+
#include <stdio.h>
5+
#include <pthread.h>
6+
7+
void longjmp_side();
8+
9+
static void* thread_main(void *arg) {
10+
jmp_buf buf;
11+
int jmpval = setjmp(buf);
12+
if (!jmpval) {
13+
printf("setjmp done\n");
14+
longjmp_side(&buf);
15+
// should never get here
16+
assert(false);
17+
} else if (jmpval == 42) {
18+
printf("longjmp done\n");
19+
} else {
20+
assert(false);
21+
}
22+
23+
return NULL;
24+
}
25+
26+
int main() {
27+
pthread_t t;
28+
int rc;
29+
30+
rc = pthread_create(&t, NULL, thread_main, NULL);
31+
assert(!rc);
32+
rc = pthread_join(t, NULL);
33+
assert(!rc);
34+
35+
printf("Done");
36+
return 0;
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
setjmp done
2+
longjmp done
3+
Done
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <setjmp.h>
2+
3+
void longjmp_side(jmp_buf* buf) {
4+
longjmp(*buf, 42); // jumps back to where setjmp was called
5+
}

tests/test_core.py

+10
Original file line numberDiff line numberDiff line change
@@ -8549,6 +8549,16 @@ def test_pthread_dylink_tls(self):
85498549
main = test_file('core/pthread/test_pthread_dylink_tls.c')
85508550
self.dylink_testf(main, need_reverse=False)
85518551

8552+
@needs_dylink
8553+
@node_pthreads
8554+
def test_pthread_dylink_longjmp(self):
8555+
self.emcc_args.append('-Wno-experimental')
8556+
self.set_setting('EXIT_RUNTIME')
8557+
self.set_setting('USE_PTHREADS')
8558+
self.set_setting('PTHREAD_POOL_SIZE=1')
8559+
main = test_file('core/pthread/test_pthread_dylink_longjmp.c')
8560+
self.dylink_testf(main, need_reverse=False)
8561+
85528562
@needs_dylink
85538563
@node_pthreads
85548564
def test_Module_dynamicLibraries_pthreads(self):

tests/test_other.py

-4
Original file line numberDiff line numberDiff line change
@@ -1675,10 +1675,6 @@ def test_dylink_pthread_warning(self):
16751675
err = self.expect_fail([EMCC, '-Werror', '-sMAIN_MODULE', '-sUSE_PTHREADS', test_file('hello_world.c')])
16761676
self.assertContained('error: -s MAIN_MODULE + pthreads is experimental', err)
16771677

1678-
def test_dylink_pthread_longjmp(self):
1679-
err = self.expect_fail([EMCC, '-sMAIN_MODULE', '-sUSE_PTHREADS', '-sSUPPORT_LONGJMP', test_file('hello_world.c')])
1680-
self.assertContained('SUPPORT_LONGJMP is not compatible with pthreads + dynamic linking', err)
1681-
16821678
def test_dylink_no_autoload(self):
16831679
create_file('main.c', r'''
16841680
#include <stdio.h>

0 commit comments

Comments
 (0)