diff --git a/src/os/bsd/vm/jsig.c b/src/os/bsd/vm/jsig.c --- a/src/os/bsd/vm/jsig.c +++ b/src/os/bsd/vm/jsig.c @@ -36,13 +36,16 @@ #include #include #include +#include #define MAXSIGNUM 32 #define MASK(sig) ((unsigned int)1 << sig) static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ static unsigned int jvmsigs = 0; /* signals used by jvm */ -static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */ + +static pthread_key_t reentry_flag_key; +static pthread_once_t reentry_key_init_once = PTHREAD_ONCE_INIT; /* used to synchronize the installation of signal handlers */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -60,6 +63,15 @@ static bool jvm_signal_installing = false; static bool jvm_signal_installed = false; +#define check_status(cmd) \ + do { \ + int status = (cmd); \ + if (status != 0) { \ + printf("error %s (%d) in " #cmd "\n", strerror(status), status); \ + exit(1); \ + } \ + } while (0) + static void signal_lock() { pthread_mutex_lock(&mutex); /* When the jvm is installing its set of signal handlers, threads @@ -75,6 +87,11 @@ pthread_mutex_unlock(&mutex); } +static void reentry_tls_init() { + // value for reentry_flag_key will default to NULL (false) + check_status(pthread_key_create(&reentry_flag_key, NULL)); +} + static sa_handler_t call_os_signal(int sig, sa_handler_t disp, bool is_sigset) { sa_handler_t res; @@ -90,9 +107,11 @@ exit(0); } } - reentry = true; + check_status(pthread_once(&reentry_key_init_once, reentry_tls_init)); + // set reentry_flag_key to non-NULL to show reentry + check_status(pthread_setspecific(reentry_flag_key, &res)); res = (*os_signal)(sig, disp); - reentry = false; + check_status(pthread_setspecific(reentry_flag_key, NULL)); return res; } @@ -167,7 +186,8 @@ bool sigused; struct sigaction oldAct; - if (reentry) { + check_status(pthread_once(&reentry_key_init_once, reentry_tls_init)); + if (pthread_getspecific(reentry_flag_key) != NULL) { return call_os_sigaction(sig, act, oact); }