aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads/pthread.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-01-07 11:53:05 +0000
committerUlrich Drepper <drepper@redhat.com>1999-01-07 11:53:05 +0000
commitb92ad8d61f18a3e9a61434e2e3252efd862bd7f4 (patch)
treea673f7750cb17ce2adaee14e9a8b4855447b6feb /linuxthreads/pthread.c
parent34992338178abc47897f10ce4fb12d204e682b14 (diff)
downloadglibc-b92ad8d61f18a3e9a61434e2e3252efd862bd7f4.tar
glibc-b92ad8d61f18a3e9a61434e2e3252efd862bd7f4.tar.gz
glibc-b92ad8d61f18a3e9a61434e2e3252efd862bd7f4.tar.bz2
glibc-b92ad8d61f18a3e9a61434e2e3252efd862bd7f4.zip
1999-01-07 Xavier Leroy <Xavier.Leroy@inria.fr>
* pthread.c: Use a third signal __pthread_sig_debug distinct from __pthread_sig_cancel to notify gdb when a thread is created * manager.c: Likewise. * internals.h: Likewise. * signals.c: The implementation of sigwait(s) assumed that all signals in s have signal handlers already attached. This is not required by the standard, so make it work also if some of the signals have no handlers.
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.