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 ;
1517bh_stack_context_handler_t stack_context_handler ;
1618
1719typedef struct {
@@ -55,19 +57,16 @@ os_thread_wrapper(void *arg)
5557static void
5658stack_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+
95111bool
96112os_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()
123139void
124140os_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
153167bool
@@ -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)
194208free_list_and_unlock :
195209 BH_FREE (context_list );
196210unlock :
197- os_mutex_unlock ( & stack_context_handler . lock );
211+ stack_ctx_unlock_and_unblock_sig ( );
198212 return false;
199213}
200214
0 commit comments