mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
2005-10-01 Ulrich Drepper <drepper@redhat.com>
Jakub Jelinek <jakub@redhat.com> * descr.h: Define SETXID_BIT and SETXID_BITMASK. Adjust CANCEL_RESTMASK. (struct pthread): Move specific_used field to avoid padding. Add setxid_futex field. * init.c (sighandler_setxid): Reset setxid flag and release the setxid futex. * allocatestack.c (setxid_signal_thread): New function. Broken out of the bodies of the two loops in __nptl_setxid. For undetached threads check whether they are exiting and if yes, don't send a signal. (__nptl_setxid): Simplify loops by using setxid_signal_thread. * pthread_create.c (start_thread): For undetached threads, check whether setxid bit is set. If yes, wait until signal has been processed. * allocatestack.c (STACK_VARIABLES): Initialize them. * pthread_create.c (__pthread_create_2_1): Initialize pd.
This commit is contained in:
parent
2ff89ea46f
commit
dff9a7a163
@ -1,3 +1,23 @@
|
||||
2005-10-01 Ulrich Drepper <drepper@redhat.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* descr.h: Define SETXID_BIT and SETXID_BITMASK. Adjust
|
||||
CANCEL_RESTMASK.
|
||||
(struct pthread): Move specific_used field to avoid padding.
|
||||
Add setxid_futex field.
|
||||
* init.c (sighandler_setxid): Reset setxid flag and release the
|
||||
setxid futex.
|
||||
* allocatestack.c (setxid_signal_thread): New function. Broken
|
||||
out of the bodies of the two loops in __nptl_setxid. For undetached
|
||||
threads check whether they are exiting and if yes, don't send a signal.
|
||||
(__nptl_setxid): Simplify loops by using setxid_signal_thread.
|
||||
* pthread_create.c (start_thread): For undetached threads, check
|
||||
whether setxid bit is set. If yes, wait until signal has been
|
||||
processed.
|
||||
|
||||
* allocatestack.c (STACK_VARIABLES): Initialize them.
|
||||
* pthread_create.c (__pthread_create_2_1): Initialize pd.
|
||||
|
||||
2004-09-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* pthread_cond_destroy.c (__pthread_cond_destroy): If there are
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
@ -33,7 +34,7 @@
|
||||
#ifndef NEED_SEPARATE_REGISTER_STACK
|
||||
|
||||
/* Most architectures have exactly one stack pointer. Some have more. */
|
||||
# define STACK_VARIABLES void *stackaddr
|
||||
# define STACK_VARIABLES void *stackaddr = NULL
|
||||
|
||||
/* How to pass the values to the 'create_thread' function. */
|
||||
# define STACK_VARIABLES_ARGS stackaddr
|
||||
@ -52,7 +53,7 @@
|
||||
|
||||
/* We need two stacks. The kernel will place them but we have to tell
|
||||
the kernel about the size of the reserved address space. */
|
||||
# define STACK_VARIABLES void *stackaddr; size_t stacksize
|
||||
# define STACK_VARIABLES void *stackaddr = NULL; size_t stacksize = 0
|
||||
|
||||
/* How to pass the values to the 'create_thread' function. */
|
||||
# define STACK_VARIABLES_ARGS stackaddr, stacksize
|
||||
@ -817,6 +818,45 @@ __find_thread_by_id (pid_t tid)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
internal_function
|
||||
setxid_signal_thread (struct xid_command *cmdp, struct pthread *t)
|
||||
{
|
||||
if (! IS_DETACHED (t))
|
||||
{
|
||||
int ch;
|
||||
do
|
||||
{
|
||||
ch = t->cancelhandling;
|
||||
|
||||
/* If the thread is exiting right now, ignore it. */
|
||||
if ((ch & EXITING_BITMASK) != 0)
|
||||
return;
|
||||
}
|
||||
while (atomic_compare_and_exchange_val_acq (&t->cancelhandling,
|
||||
ch | SETXID_BITMASK, ch));
|
||||
}
|
||||
|
||||
int val;
|
||||
#if __ASSUME_TGKILL
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
#else
|
||||
# ifdef __NR_tgkill
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
if (INTERNAL_SYSCALL_ERROR_P (val, err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
|
||||
# endif
|
||||
val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
|
||||
#endif
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (val, err))
|
||||
atomic_increment (&cmdp->cntr);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
attribute_hidden
|
||||
__nptl_setxid (struct xid_command *cmdp)
|
||||
@ -836,54 +876,20 @@ __nptl_setxid (struct xid_command *cmdp)
|
||||
list_for_each (runp, &stack_used)
|
||||
{
|
||||
struct pthread *t = list_entry (runp, struct pthread, list);
|
||||
if (t != self)
|
||||
{
|
||||
int val;
|
||||
#if __ASSUME_TGKILL
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3,
|
||||
THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
#else
|
||||
# ifdef __NR_tgkill
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3,
|
||||
THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
if (INTERNAL_SYSCALL_ERROR_P (val, err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
|
||||
# endif
|
||||
val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
|
||||
#endif
|
||||
if (t == self)
|
||||
continue;
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (val, err))
|
||||
atomic_increment (&cmdp->cntr);
|
||||
}
|
||||
setxid_signal_thread (cmdp, t);
|
||||
}
|
||||
|
||||
/* Now the list with threads using user-allocated stacks. */
|
||||
list_for_each (runp, &__stack_user)
|
||||
{
|
||||
struct pthread *t = list_entry (runp, struct pthread, list);
|
||||
if (t != self)
|
||||
{
|
||||
int val;
|
||||
#if __ASSUME_TGKILL
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3,
|
||||
THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
#else
|
||||
# ifdef __NR_tgkill
|
||||
val = INTERNAL_SYSCALL (tgkill, err, 3,
|
||||
THREAD_GETMEM (THREAD_SELF, pid),
|
||||
t->tid, SIGSETXID);
|
||||
if (INTERNAL_SYSCALL_ERROR_P (val, err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
|
||||
# endif
|
||||
val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
|
||||
#endif
|
||||
if (t == self)
|
||||
continue;
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (val, err))
|
||||
atomic_increment (&cmdp->cntr);
|
||||
}
|
||||
setxid_signal_thread (cmdp, t);
|
||||
}
|
||||
|
||||
int cur = cmdp->cntr;
|
||||
|
16
nptl/descr.h
16
nptl/descr.h
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
@ -161,8 +161,11 @@ struct pthread
|
||||
/* Bit set if thread terminated and TCB is freed. */
|
||||
#define TERMINATED_BIT 5
|
||||
#define TERMINATED_BITMASK 0x20
|
||||
/* Bit set if thread is supposed to change XID. */
|
||||
#define SETXID_BIT 6
|
||||
#define SETXID_BITMASK 0x40
|
||||
/* Mask for the rest. Helps the compiler to optimize. */
|
||||
#define CANCEL_RESTMASK 0xffffffc0
|
||||
#define CANCEL_RESTMASK 0xffffff80
|
||||
|
||||
#define CANCEL_ENABLED_AND_CANCELED(value) \
|
||||
(((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK \
|
||||
@ -185,12 +188,12 @@ struct pthread
|
||||
void *data;
|
||||
} specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
|
||||
|
||||
/* Flag which is set when specific data is set. */
|
||||
bool specific_used;
|
||||
|
||||
/* Two-level array for the thread-specific data. */
|
||||
struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
|
||||
|
||||
/* Flag which is set when specific data is set. */
|
||||
bool specific_used;
|
||||
|
||||
/* True if events must be reported. */
|
||||
bool report_events;
|
||||
|
||||
@ -203,6 +206,9 @@ struct pthread
|
||||
/* Lock to synchronize access to the descriptor. */
|
||||
lll_lock_t lock;
|
||||
|
||||
/* Lock for synchronizing setxid calls. */
|
||||
lll_lock_t setxid_futex;
|
||||
|
||||
#if HP_TIMING_AVAIL
|
||||
/* Offset of the CPU clock at start thread start time. */
|
||||
hp_timing_t cpuclock_offset;
|
||||
|
11
nptl/init.c
11
nptl/init.c
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
@ -211,6 +211,15 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
|
||||
|
||||
if (atomic_decrement_val (&__xidcmd->cntr) == 0)
|
||||
lll_futex_wake (&__xidcmd->cntr, 1);
|
||||
|
||||
/* Reset the SETXID flag. */
|
||||
struct pthread *self = THREAD_SELF;
|
||||
int flags = THREAD_GETMEM (self, cancelhandling);
|
||||
THREAD_SETMEM (self, cancelhandling, flags & ~SETXID_BITMASK);
|
||||
|
||||
/* And release the futex. */
|
||||
self->setxid_futex = 1;
|
||||
lll_futex_wake (&self->setxid_futex, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,6 +314,17 @@ start_thread (void *arg)
|
||||
if (IS_DETACHED (pd))
|
||||
/* Free the TCB. */
|
||||
__free_tcb (pd);
|
||||
else if (__builtin_expect (pd->cancelhandling & SETXID_BITMASK, 0))
|
||||
{
|
||||
/* Some other thread might call any of the setXid functions and expect
|
||||
us to reply. In this case wait until we did that. */
|
||||
do
|
||||
lll_futex_wait (&pd->setxid_futex, 0);
|
||||
while (pd->cancelhandling & SETXID_BITMASK);
|
||||
|
||||
/* Reset the value so that the stack can be reused. */
|
||||
pd->setxid_futex = 0;
|
||||
}
|
||||
|
||||
/* We cannot call '_exit' here. '_exit' will terminate the process.
|
||||
|
||||
@ -354,7 +365,7 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
|
||||
accessing far-away memory. */
|
||||
iattr = &default_attr;
|
||||
|
||||
struct pthread *pd;
|
||||
struct pthread *pd = NULL;
|
||||
int err = ALLOCATE_STACK (iattr, &pd);
|
||||
if (__builtin_expect (err != 0, 0))
|
||||
/* Something went wrong. Maybe a parameter of the attributes is
|
||||
|
Loading…
Reference in New Issue
Block a user