about summary refs log tree commit diff
path: root/linuxthreads/pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/pthread.c')
-rw-r--r--linuxthreads/pthread.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 8d892b7bb5..29e7682105 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -150,9 +150,11 @@ const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct,
 #ifdef SIGRTMIN
 int __pthread_sig_restart;
 int __pthread_sig_cancel;
+int __pthread_sig_debug;
 #else
 int __pthread_sig_restart = DEFAULT_SIG_RESTART;
 int __pthread_sig_cancel = DEFAULT_SIG_CANCEL;
+int __pthread_sig_debug = 0;    /* disabled */
 #endif
 
 /* These variables are used by the setup code.  */
@@ -169,6 +171,7 @@ static void pthread_handle_sigrestart(int sig);
 static void pthread_handle_sigcancel(int sig, struct sigcontext ctx);
 static void pthread_handle_sigrestart(int sig, struct sigcontext ctx);
 #endif
+static void pthread_handle_sigdebug(int sig);
 
 /* Initialize the pthread library.
    Initialization is split in two functions:
@@ -220,12 +223,17 @@ static void pthread_initialize(void)
   /* Allocate the signals used.  */
   __pthread_sig_restart = __libc_allocate_rtsig (1);
   __pthread_sig_cancel = __libc_allocate_rtsig (1);
-  if (__pthread_sig_restart < 0 || __pthread_sig_cancel < 0)
+  __pthread_sig_debug = __libc_allocate_rtsig (2);
+  if (__pthread_sig_restart < 0 ||
+      __pthread_sig_cancel < 0 ||
+      __pthread_sig_debug < 0)
     {
       /* The kernel does not support real-time signals.  Use as before
-	 the available signals in the fixed set.  */
+	 the available signals in the fixed set.
+         Debugging is not supported in this case. */
       __pthread_sig_restart = DEFAULT_SIG_RESTART;
       __pthread_sig_cancel = DEFAULT_SIG_CANCEL;
+      __pthread_sig_debug = 0;
     }
 #endif
   /* Setup signal handlers for the initial thread.
@@ -237,8 +245,7 @@ static void pthread_initialize(void)
   sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart;
 #endif
   sigemptyset(&sa.sa_mask);
-  sa.sa_flags = SA_RESTART; /* does not matter for regular threads, but
-                               better for the thread manager */
+  sa.sa_flags = 0;
   __sigaction(__pthread_sig_restart, &sa, NULL);
 #ifndef __i386__
   sa.sa_handler = pthread_handle_sigcancel;
@@ -247,7 +254,12 @@ static void pthread_initialize(void)
 #endif
   sa.sa_flags = 0;
   __sigaction(__pthread_sig_cancel, &sa, NULL);
-
+  if (__pthread_sig_debug > 0) {
+    sa.sa_handler = pthread_handle_sigdebug;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    __sigaction(__pthread_sig_debug, &sa, NULL);
+  }
   /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */
   sigemptyset(&mask);
   sigaddset(&mask, __pthread_sig_restart);
@@ -479,16 +491,8 @@ static void pthread_handle_sigrestart(int sig, struct sigcontext ctx)
 
 /* The handler for the CANCEL signal checks for cancellation
    (in asynchronous mode), for process-wide exit and exec requests.
-   For the thread manager thread, redirect the signal to 
-   __pthread_manager_sighandler.
-   The debugging strategy is as follows:
-   On reception of a REQ_DEBUG request (sent by new threads created to
-   the thread manager under debugging mode), the thread manager throws
-   __pthread_sig_cancel to itself. The debugger (if active) intercepts
-   this signal, takes into account new threads and continue execution
-   of the thread manager by propagating the signal because it doesn't
-   know what it is specifically done for. In the current implementation,
-   the thread manager simply discards it. */
+   For the thread manager thread, redirect the signal to
+   __pthread_manager_sighandler. */
 
 #ifndef __i386__
 static void pthread_handle_sigcancel(int sig)
@@ -528,6 +532,21 @@ static void pthread_handle_sigcancel(int sig, struct sigcontext ctx)
   }
 }
 
+/* Handler for the DEBUG signal.
+   The debugging strategy is as follows:
+   On reception of a REQ_DEBUG request (sent by new threads created to
+   the thread manager under debugging mode), the thread manager throws
+   __pthread_sig_cancel to itself. The debugger (if active) intercepts
+   this signal, takes into account new threads and continue execution
+   of the thread manager by propagating the signal because it doesn't
+   know what it is specifically done for. In the current implementation,
+   the thread manager simply discards it. */
+
+static void pthread_handle_sigdebug(int sig)
+{
+  /* Nothing */
+}
+
 /* Reset the state of the thread machinery after a fork().
    Close the pipe used for requests and set the main thread to the forked
    thread.