]> granicus.if.org Git - gc/commitdiff
Added abort() and exit() callback hooks.
authorJean-Claude Beaudoin <jean.claude.beaudoin@gmail.com>
Fri, 22 Jun 2012 03:16:32 +0000 (23:16 -0400)
committerJean-Claude Beaudoin <jean.claude.beaudoin@gmail.com>
Fri, 22 Jun 2012 03:16:32 +0000 (23:16 -0400)
Added SIG_SUSPEND and SIG_THR_RESTART configuration at GC_init() time.

include/gc.h
include/private/gc_priv.h
misc.c
pthread_stop_world.c

index f9405bb3205fd9b32a75db7bffaad4dcf31b4c0e..d4791c0484183d057c61f9fe9db14d1394f00cc4 100644 (file)
@@ -1610,6 +1610,21 @@ GC_API void GC_CALL GC_win32_free_heap(void);
         (*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_ignore_off_page)
 #endif /* _AMIGA && !GC_AMIGA_MAKINGLIB */
 
+
+typedef void (*GC_exit_func)(const int status);
+
+GC_API void GC_CALL GC_set_exit_func(GC_exit_func fn);
+
+typedef void (*GC_abort_func)(const char * const msg);
+
+GC_API void GC_CALL GC_set_abort_func(GC_abort_func fn);
+
+#if defined(GC_LINUX_THREADS)
+GC_API void GC_CALL GC_set_suspend_signal(const int sig);
+GC_API void GC_CALL GC_set_thr_restart_signal(const int sig);
+#endif
+
+
 #ifdef __cplusplus
   }  /* end of extern "C" */
 #endif
index f7641deadb688c64a8db87a76ad3640bbe38dfd6..91695132f753cf693b092d33b8115a2a5801a8e6 100644 (file)
@@ -493,7 +493,8 @@ typedef char * ptr_t;   /* A generic pointer to which we can add        */
 # ifdef PCR
 #   define EXIT() PCR_Base_Exit(1,PCR_waitForever)
 # else
-#   define EXIT() (void)exit(1)
+    GC_API_PRIV void GC_exit(int status);
+#   define EXIT() GC_exit(1)
 # endif
 
 /* Print warning message, e.g. almost out of memory.    */
@@ -2286,7 +2287,10 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
 #     define SIG_SUSPEND SIGLOST
 #   else
       /* Linuxthreads itself uses SIGUSR1 and SIGUSR2.                  */
-#     define SIG_SUSPEND SIGPWR
+#     define SIG_SUSPEND GC_get_suspend_signal()
+#     define SIG_THR_RESTART GC_get_thr_restart_signal()
+#     define SIG_SUSPEND_DEFAULT SIGPWR
+#     define SIG_THR_RESTART_DEFAULT SIGXCPU
 #   endif
 # elif !defined(GC_OPENBSD_THREADS) && !defined(GC_DARWIN_THREADS)
 #   if defined(_SIGRTMIN)
diff --git a/misc.c b/misc.c
index ad3ac09253d5676a47b0a1d2355d3d466a7dd5a6..00a0e18dc0d54085983bb11962c27509e9974de6 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -509,21 +509,40 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size,
 
 
 #ifdef THREADS
-  GC_API int GC_CALL GC_get_suspend_signal(void)
-  {
+static int suspend_signal = SIG_SUSPEND_DEFAULT;
+static int thread_restart_signal = SIG_THR_RESTART_DEFAULT;
+
+void GC_set_suspend_signal(const int sig)
+{
+  if (GC_is_initialized) return;
+  suspend_signal = sig;
+}
+
+void GC_set_thread_restart_signal(const int sig)
+{
+  if (GC_is_initialized) return;
+  thread_restart_signal = sig;
+}
+
+
+    GC_API int GC_CALL GC_get_suspend_signal(void)
+    {
 #   ifdef SIG_SUSPEND
-      return SIG_SUSPEND;
+      return suspend_signal;
 #   else
       return -1;
 #   endif
-  }
+    }
 
-# if defined(GC_DARWIN_THREADS) || defined(GC_WIN32_THREADS)
     GC_API int GC_CALL GC_get_thr_restart_signal(void)
     {
+#   ifdef SIG_THR_RESTART
+      return thread_restart_signal;
+#   else      
       return -1; /* GC does not use signals to restart threads. */
+#   endif
     }
-# endif
+
 #endif /* THREADS */
 
 #if !defined(_MAX_PATH) && (defined(MSWIN32) || defined(MSWINCE) \
@@ -1459,10 +1478,19 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void)
     return(result);
 }
 
+static GC_abort_func abort_fn = NULL; /* JCB */
+
+GC_API void GC_CALL GC_set_abort_func(GC_abort_func fn)
+{
+  abort_fn = fn;
+}
+
+
 #if !defined(PCR) && !defined(SMALL_CONFIG)
   /* Print (or display) a message before abort. msg must not be NULL. */
   void GC_on_abort(const char *msg)
   {
+    if (abort_fn) abort_fn(msg);
 #   if defined(MSWIN32)
 #     ifndef DONT_USE_USER32_DLL
         /* Use static binding to "user32.dll".  */
@@ -1499,6 +1527,20 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void)
   }
 #endif /* !SMALL_CONFIG */
 
+static GC_exit_func exit_fn = NULL;
+
+void GC_exit(int status)
+{
+  if (exit_fn) exit_fn(status);
+  (void) exit(status);
+}
+
+GC_API void GC_CALL GC_set_exit_func(GC_exit_func fn)
+{
+  exit_fn = fn;
+}
+
+
 GC_API void GC_CALL GC_enable(void)
 {
     DCL_LOCK_STATE;
index a299f7543aeb4f002d834ad42fff2d3d1700189f..3723fd8199895153b7822ec96fe77042556c288e 100644 (file)
@@ -888,13 +888,4 @@ GC_INNER void GC_stop_init(void)
 # endif /* !GC_OPENBSD_THREADS && !NACL */
 }
 
-  GC_API int GC_CALL GC_get_thr_restart_signal(void)
-  {
-#   if !defined(GC_OPENBSD_THREADS) && !defined(NACL)
-      return SIG_THR_RESTART;
-#   else
-      return -1;
-#   endif
-  }
-
 #endif