2003-12-23  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/raise.c (raise): Protect pid = selftid
	setting with __ASSUME_TGKILL || defined __NR_tgkill.
	If pid is 0, set it to selftid.
	* sysdeps/unix/sysv/linux/getpid.c (really_getpid): Make inline.
	Don't set self->pid but self->tid.  If self->pid == 0 and self->tid
	!= 0, return self->tid without doing a syscall.
	* descr.h (struct pthread): Move pid field after tid.

	* Makefile (tests): Add tst-raise1.
	* tst-raise1.c: New file.
This commit is contained in:
Ulrich Drepper 2003-12-27 07:38:25 +00:00
parent dc8527f647
commit cb5b9388da
6 changed files with 88 additions and 20 deletions

View File

@ -1,3 +1,16 @@
2003-12-23 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/raise.c (raise): Protect pid = selftid
setting with __ASSUME_TGKILL || defined __NR_tgkill.
If pid is 0, set it to selftid.
* sysdeps/unix/sysv/linux/getpid.c (really_getpid): Make inline.
Don't set self->pid but self->tid. If self->pid == 0 and self->tid
!= 0, return self->tid without doing a syscall.
* descr.h (struct pthread): Move pid field after tid.
* Makefile (tests): Add tst-raise1.
* tst-raise1.c: New file.
2003-12-23 Roland McGrath <roland@redhat.com>
* tst-oddstacklimit.c: New file.

View File

@ -205,6 +205,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
tst-align \
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
tst-raise1 \
tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 \
tst-detach1 \
tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \

View File

@ -121,6 +121,9 @@ struct pthread
therefore stack) used' flag. */
pid_t tid;
/* Process ID - thread group ID in kernel speak. */
pid_t pid;
/* List of cleanup buffers. */
struct _pthread_cleanup_buffer *cleanup;
@ -178,9 +181,6 @@ struct pthread
/* Two-level array for the thread-specific data. */
struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
/* Process ID - thread group ID in kernel speak. */
pid_t pid;
/* True if events must be reported. */
bool report_events;

View File

@ -23,32 +23,42 @@
#ifndef NOT_IN_libc
static pid_t really_getpid (pid_t oldval);
#endif
static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval);
static inline __attribute__((always_inline)) pid_t
really_getpid (pid_t oldval)
{
pid_t selftid;
if (__builtin_expect (oldval == 0
&& ((selftid = THREAD_GETMEM (THREAD_SELF, tid))
!= 0), 1))
return selftid;
INTERNAL_SYSCALL_DECL (err);
pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
/* We do not set the PID field in the TID here since we might be
called from a signal handler while the thread executes fork. */
if (oldval == 0)
THREAD_SETMEM (THREAD_SELF, tid, result);
return result;
}
#endif
pid_t
__getpid (void)
{
#ifndef NOT_IN_libc
#ifdef NOT_IN_libc
INTERNAL_SYSCALL_DECL (err);
pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
#else
pid_t result = THREAD_GETMEM (THREAD_SELF, pid);
if (__builtin_expect (result <= 0, 0))
result = really_getpid (result);
#endif
return result;
}
static pid_t
really_getpid (pid_t oldval)
{
#endif
INTERNAL_SYSCALL_DECL (err);
pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
#ifndef NOT_IN_libc
if (oldval == 0)
THREAD_SETMEM (THREAD_SELF, pid, result);
#endif
return result;
}
libc_hidden_def (__getpid)
weak_alias (__getpid, getpid)
libc_hidden_def (getpid)

View File

@ -44,17 +44,19 @@ raise (sig)
#endif
THREAD_SETMEM (pd, tid, selftid);
#if __ASSUME_TGKILL || defined __NR_tgkill
/* We do not set the PID field in the TID here since we might be
called from a signal handler while the thread executes fork. */
pid = selftid;
#endif
}
#if __ASSUME_TGKILL || defined __NR_tgkill
else
/* raise is an async-safe function. It could be called while the
fork function temporarily invalidated the PID field. Adjust for
that. */
if (__builtin_expect (pid < 0, 0))
pid = -pid;
if (__builtin_expect (pid <= 0, 0))
pid = pid == 0 ? selftid : -pid;
#endif
#if __ASSUME_TGKILL

42
nptl/tst-raise1.c Normal file
View File

@ -0,0 +1,42 @@
#include <errno.h>
#include <error.h>
#include <signal.h>
#include <stdlib.h>
volatile int count;
void
sh (int sig)
{
++count;
}
int
main (void)
{
struct sigaction sa;
sa.sa_handler = sh;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction (SIGUSR1, &sa, NULL) < 0)
{
printf ("sigaction failed: %m\n");
exit (1);
}
if (raise (SIGUSR1) < 0)
{
printf ("first raise failed: %m\n");
exit (1);
}
if (raise (SIGUSR1) < 0)
{
printf ("second raise failed: %m\n");
exit (1);
}
if (count != 2)
{
printf ("signal handler not called 2 times\n");
exit (1);
}
exit (0);
}