changeset 9408:660fa1b69f63

8072147: Preloading libjsig.dylib causes deadlock when signal() is called Summary: Added check to prevent reentry of signal chaining code Reviewed-by: dcubed, acorn, dholmes
author dbuck
date Tue, 30 Jun 2015 15:26:20 -0700
parents 27d580c7af7a
children 97f63e5ca070 381272dfdd9f
files src/os/bsd/vm/jsig.c
diffstat 1 files changed, 12 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/bsd/vm/jsig.c	Tue Jun 30 09:48:24 2015 -0700
+++ b/src/os/bsd/vm/jsig.c	Tue Jun 30 15:26:20 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
 
 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) */
 
 /* used to synchronize the installation of signal handlers */
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -76,6 +77,8 @@
 
 static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
                                    bool is_sigset) {
+  sa_handler_t res;
+
   if (os_signal == NULL) {
     if (!is_sigset) {
       os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
@@ -87,7 +90,10 @@
       exit(0);
     }
   }
-  return (*os_signal)(sig, disp);
+  reentry = true;
+  res = (*os_signal)(sig, disp);
+  reentry = false;
+  return res;
 }
 
 static void save_signal_handler(int sig, sa_handler_t disp) {
@@ -161,6 +167,10 @@
   bool sigused;
   struct sigaction oldAct;
 
+  if (reentry) {
+    return call_os_sigaction(sig, act, oact);
+  }
+
   signal_lock();
 
   sigused = (MASK(sig) & jvmsigs) != 0;