1212#include "bh_hashmap.h"
1313#include <setjmp.h>
1414
15+ #define STACK_CTX_SIG SIGUSR1
16+ 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,11 @@ os_stack_contexts_init()
123139void
124140os_stack_contexts_destroy ()
125141{
126- os_mutex_lock ( & stack_context_handler . lock );
142+ stack_ctx_block_sig_and_lock ( );
127143 if (!bh_hash_map_destroy (stack_context_handler .contexts ))
128144 LOG_ERROR ("failed to destroy stack context map" );
129145 stack_context_handler .contexts = NULL ;
130- os_mutex_unlock ( & stack_context_handler . lock );
146+ stack_ctx_unlock_and_unblock_sig ( );
131147
132148 if (os_mutex_destroy (& stack_context_handler .lock ) != BHT_OK )
133149 LOG_ERROR ("failed to destroy stack contexts" );
@@ -138,7 +154,7 @@ os_remove_stack_context(korp_tid handle, sigjmp_buf *context)
138154{
139155 korp_tid self = pthread_self ();
140156
141- os_mutex_lock ( & stack_context_handler . lock );
157+ stack_ctx_block_sig_and_lock ( );
142158
143159 bh_list * context_list = bh_hash_map_find (stack_context_handler .contexts ,
144160 (void * )(uintptr_t )self );
@@ -147,7 +163,7 @@ os_remove_stack_context(korp_tid handle, sigjmp_buf *context)
147163 assert (ret == BH_LIST_SUCCESS );
148164 BH_FREE (context );
149165
150- os_mutex_unlock ( & stack_context_handler . lock );
166+ stack_ctx_unlock_and_unblock_sig ( );
151167}
152168
153169bool
@@ -156,7 +172,7 @@ os_is_returning_from_signal(korp_tid handle, sigjmp_buf *context)
156172 if (sigsetjmp (* context , 1 ))
157173 return true;
158174
159- os_mutex_lock ( & stack_context_handler . lock );
175+ stack_ctx_block_sig_and_lock ( );
160176
161177 /* Get or create list of stack contexts for current thread */
162178 bh_list * context_list = bh_hash_map_find (stack_context_handler .contexts ,
@@ -194,7 +210,7 @@ os_is_returning_from_signal(korp_tid handle, sigjmp_buf *context)
194210free_list_and_unlock :
195211 BH_FREE (context_list );
196212unlock :
197- os_mutex_unlock ( & stack_context_handler . lock );
213+ stack_ctx_unlock_and_unblock_sig ( );
198214 return false;
199215}
200216
0 commit comments