Skip to content

Commit 57d208d

Browse files
committed
fix(wasi-threads): do not use mutex in signal handler
1 parent d70da2f commit 57d208d

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

core/shared/platform/common/posix/posix_thread.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "bh_hashmap.h"
1313
#include <setjmp.h>
1414

15+
#define STACK_CTX_SIG SIGUSR1
16+
static os_thread_local_attribute sigset_t newmask, oldmask;
1517
bh_stack_context_handler_t stack_context_handler;
1618

1719
typedef struct {
@@ -55,19 +57,16 @@ os_thread_wrapper(void *arg)
5557
static void
5658
stack_context_sig_handler(int sig)
5759
{
58-
assert(sig == SIGUSR1);
60+
assert(sig == STACK_CTX_SIG);
5961
korp_tid self = pthread_self();
6062

61-
os_mutex_lock(&stack_context_handler.lock);
62-
6363
/* Get latest stack context (first in the list) for current thread */
6464
bh_list *context_list = bh_hash_map_find(stack_context_handler.contexts,
6565
(void *)(uintptr_t)self);
6666
assert(context_list);
6767
sigjmp_buf *context = bh_list_first_elem(context_list);
6868
assert(context);
6969

70-
os_mutex_unlock(&stack_context_handler.lock);
7170
siglongjmp(*context, 1);
7271
}
7372

@@ -92,14 +91,31 @@ free_stack_context_list(void *stack_context_list)
9291
BH_FREE(context_list);
9392
}
9493

94+
static inline void
95+
stack_ctx_block_sig_and_lock()
96+
{
97+
sigemptyset(&newmask);
98+
sigaddset(&newmask, STACK_CTX_SIG);
99+
pthread_sigmask(SIG_BLOCK, &newmask, &oldmask);
100+
101+
os_mutex_lock(&stack_context_handler.lock);
102+
}
103+
104+
static inline void
105+
stack_ctx_unlock_and_unblock_sig()
106+
{
107+
os_mutex_unlock(&stack_context_handler.lock);
108+
pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
109+
}
110+
95111
bool
96112
os_stack_contexts_init()
97113
{
98114
struct sigaction act;
99115
memset(&act, 0, sizeof(act));
100116
act.sa_handler = stack_context_sig_handler;
101117
sigfillset(&act.sa_mask);
102-
if (sigaction(SIGUSR1, &act, NULL) < 0) {
118+
if (sigaction(STACK_CTX_SIG, &act, NULL) < 0) {
103119
LOG_ERROR("failed to set signal handler");
104120
return false;
105121
}
@@ -123,11 +139,9 @@ os_stack_contexts_init()
123139
void
124140
os_stack_contexts_destroy()
125141
{
126-
os_mutex_lock(&stack_context_handler.lock);
127142
if (!bh_hash_map_destroy(stack_context_handler.contexts))
128143
LOG_ERROR("failed to destroy stack context map");
129144
stack_context_handler.contexts = NULL;
130-
os_mutex_unlock(&stack_context_handler.lock);
131145

132146
if (os_mutex_destroy(&stack_context_handler.lock) != BHT_OK)
133147
LOG_ERROR("failed to destroy stack contexts");
@@ -138,7 +152,7 @@ os_remove_stack_context(korp_tid handle, sigjmp_buf *context)
138152
{
139153
korp_tid self = pthread_self();
140154

141-
os_mutex_lock(&stack_context_handler.lock);
155+
stack_ctx_block_sig_and_lock();
142156

143157
bh_list *context_list = bh_hash_map_find(stack_context_handler.contexts,
144158
(void *)(uintptr_t)self);
@@ -147,7 +161,7 @@ os_remove_stack_context(korp_tid handle, sigjmp_buf *context)
147161
assert(ret == BH_LIST_SUCCESS);
148162
BH_FREE(context);
149163

150-
os_mutex_unlock(&stack_context_handler.lock);
164+
stack_ctx_unlock_and_unblock_sig();
151165
}
152166

153167
bool
@@ -156,7 +170,7 @@ os_is_returning_from_signal(korp_tid handle, sigjmp_buf *context)
156170
if (sigsetjmp(*context, 1))
157171
return true;
158172

159-
os_mutex_lock(&stack_context_handler.lock);
173+
stack_ctx_block_sig_and_lock();
160174

161175
/* Get or create list of stack contexts for current thread */
162176
bh_list *context_list = bh_hash_map_find(stack_context_handler.contexts,
@@ -194,7 +208,7 @@ os_is_returning_from_signal(korp_tid handle, sigjmp_buf *context)
194208
free_list_and_unlock:
195209
BH_FREE(context_list);
196210
unlock:
197-
os_mutex_unlock(&stack_context_handler.lock);
211+
stack_ctx_unlock_and_unblock_sig();
198212
return false;
199213
}
200214

0 commit comments

Comments
 (0)