Skip to content

Commit 2e279b8

Browse files
committed
Add more testing for pthread_kill.
- Test using `pthread_kill` on yourself. - Test using `pthread_kill` from a background thread to the main thread.
1 parent c22a176 commit 2e279b8

File tree

3 files changed

+50
-22
lines changed

3 files changed

+50
-22
lines changed

system/lib/pthread/pthread_kill.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
#include "pthread_impl.h"
1414
#include "lock.h"
1515

16-
void do_raise(void* arg) {
17-
int sig = (intptr_t)arg;
16+
17+
18+
static void do_raise(int sig) {
1819
if (sig == SIGCANCEL) {
1920
// For `SIGCANCEL` there is no need to actually call raise to run the
2021
// handler function. The calling thread (the one calling `pthread_cancel`)
@@ -31,24 +32,28 @@ void do_raise(void* arg) {
3132
_emscripten_runtime_keepalive_clear();
3233
return;
3334
}
34-
raise((intptr_t)sig);
35+
raise(sig);
36+
}
37+
38+
static void procied_do_raise(void* arg) {
39+
do_raise((intptr_t)arg);
3540
}
3641

3742
int pthread_kill(pthread_t t, int sig) {
3843
if (sig < 0 || sig >= _NSIG) {
3944
return EINVAL;
4045
}
41-
if (t == emscripten_main_runtime_thread_id()) {
42-
if (sig == 0) return 0; // signal == 0 is a no-op.
43-
return ESRCH;
44-
}
4546
if (!t || !_emscripten_thread_is_valid(t)) {
4647
return ESRCH;
4748
}
4849
if (sig == 0) return 0; // signal == 0 is a no-op.
4950

50-
// The job of pthread_kill is basically to run the (process-wide) signal
51-
// handler on the target thread.
52-
emscripten_proxy_async(emscripten_proxy_get_system_queue(), t, do_raise, (void*)(intptr_t)sig);
51+
if (pthread_equal(pthread_self(), t)) {
52+
do_raise(sig);
53+
} else {
54+
// The job of pthread_kill is basically to run the (process-wide) signal
55+
// handler on the target thread.
56+
emscripten_proxy_async(emscripten_proxy_get_system_queue(), t, procied_do_raise, (void*)(intptr_t)sig);
57+
}
5358
return 0;
5459
}

test/pthread/test_pthread_kill.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@
1717

1818
pthread_cond_t started_cond = PTHREAD_COND_INITIALIZER;
1919
pthread_mutex_t started_lock = PTHREAD_MUTEX_INITIALIZER;
20-
_Atomic bool got_term_signal = false;
20+
_Atomic bool got_sigterm = false;
21+
_Atomic bool got_sigusr1 = false;
2122

22-
pthread_t thr;
23+
pthread_t main_thread;
24+
pthread_t child_thread;
2325

2426
void signal_handler(int sig, siginfo_t * info, void * arg) {
25-
printf("signal: %d onthread=%d\n", sig, pthread_self() == thr);
27+
printf("signal: %d onthread=%d\n", sig, pthread_self() == child_thread);
2628
if (sig == SIGTERM) {
27-
got_term_signal = true;
29+
got_sigterm = true;
30+
} else if (sig == SIGUSR1) {
31+
got_sigusr1 = true;
2832
}
2933
}
3034

@@ -34,6 +38,7 @@ void setup_handler() {
3438
act.sa_flags = SA_SIGINFO;
3539
act.sa_sigaction = signal_handler;
3640
sigaction(SIGTERM, &act, NULL);
41+
sigaction(SIGUSR1, &act, NULL);
3742
}
3843

3944

@@ -46,17 +51,26 @@ void *thread_start(void *arg) {
4651
pthread_cond_signal(&started_cond);
4752
pthread_mutex_unlock(&started_lock);
4853
// As long as this thread is running, keep the shared variable latched to nonzero value.
49-
while (!got_term_signal) {
54+
while (!got_sigterm) {
5055
sleepms(1);
5156
}
52-
printf("got term signal, shutting down thread\n");
53-
pthread_exit(0);
57+
printf("got term signal, sending signal back to main thread\n");
58+
pthread_kill(main_thread, SIGUSR1);
59+
return NULL;
5460
}
5561

5662
int main() {
63+
main_thread = pthread_self();
5764
setup_handler();
5865

59-
int s = pthread_create(&thr, NULL, thread_start, 0);
66+
printf("tesing pthread_kill with pthread_self\n");
67+
assert(!got_sigterm);
68+
int s = pthread_kill(pthread_self(), SIGTERM);
69+
assert(got_sigterm);
70+
got_sigterm = false;
71+
assert(s == 0);
72+
73+
s = pthread_create(&child_thread, NULL, thread_start, 0);
6074
assert(s == 0);
6175

6276
// Wait until thread kicks in and sets the shared variable.
@@ -65,11 +79,15 @@ int main() {
6579
pthread_mutex_unlock(&started_lock);
6680
printf("thread has started, sending SIGTERM\n");
6781

68-
s = pthread_kill(thr, SIGTERM);
82+
s = pthread_kill(child_thread, SIGTERM);
6983
assert(s == 0);
7084
printf("SIGTERM sent\n");
7185

72-
73-
pthread_join(thr, NULL);
86+
pthread_join(child_thread, NULL);
87+
printf("joined child_thread\n");
88+
while (!got_sigusr1) {
89+
sleepms(1);
90+
}
91+
printf("got SIGUSR1. all done.\n");
7492
return 0;
7593
}

test/pthread/test_pthread_kill.out

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
tesing pthread_kill with pthread_self
2+
signal: 15 onthread=0
13
thread has started, sending SIGTERM
24
SIGTERM sent
35
signal: 15 onthread=1
4-
got term signal, shutting down thread
6+
got term signal, sending signal back to main thread
7+
joined child_thread
8+
signal: 10 onthread=0
9+
got SIGUSR1. all done.

0 commit comments

Comments
 (0)