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>
|
2004-09-02 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* pthread_cond_destroy.c (__pthread_cond_destroy): If there are
|
* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
@ -33,7 +34,7 @@
|
|||||||
#ifndef NEED_SEPARATE_REGISTER_STACK
|
#ifndef NEED_SEPARATE_REGISTER_STACK
|
||||||
|
|
||||||
/* Most architectures have exactly one stack pointer. Some have more. */
|
/* 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. */
|
/* How to pass the values to the 'create_thread' function. */
|
||||||
# define STACK_VARIABLES_ARGS stackaddr
|
# define STACK_VARIABLES_ARGS stackaddr
|
||||||
@ -52,7 +53,7 @@
|
|||||||
|
|
||||||
/* We need two stacks. The kernel will place them but we have to tell
|
/* We need two stacks. The kernel will place them but we have to tell
|
||||||
the kernel about the size of the reserved address space. */
|
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. */
|
/* How to pass the values to the 'create_thread' function. */
|
||||||
# define STACK_VARIABLES_ARGS stackaddr, stacksize
|
# define STACK_VARIABLES_ARGS stackaddr, stacksize
|
||||||
@ -817,6 +818,45 @@ __find_thread_by_id (pid_t tid)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
int
|
||||||
attribute_hidden
|
attribute_hidden
|
||||||
__nptl_setxid (struct xid_command *cmdp)
|
__nptl_setxid (struct xid_command *cmdp)
|
||||||
@ -836,54 +876,20 @@ __nptl_setxid (struct xid_command *cmdp)
|
|||||||
list_for_each (runp, &stack_used)
|
list_for_each (runp, &stack_used)
|
||||||
{
|
{
|
||||||
struct pthread *t = list_entry (runp, struct pthread, list);
|
struct pthread *t = list_entry (runp, struct pthread, list);
|
||||||
if (t != self)
|
if (t == self)
|
||||||
{
|
continue;
|
||||||
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))
|
setxid_signal_thread (cmdp, t);
|
||||||
atomic_increment (&cmdp->cntr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now the list with threads using user-allocated stacks. */
|
/* Now the list with threads using user-allocated stacks. */
|
||||||
list_for_each (runp, &__stack_user)
|
list_for_each (runp, &__stack_user)
|
||||||
{
|
{
|
||||||
struct pthread *t = list_entry (runp, struct pthread, list);
|
struct pthread *t = list_entry (runp, struct pthread, list);
|
||||||
if (t != self)
|
if (t == self)
|
||||||
{
|
continue;
|
||||||
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))
|
setxid_signal_thread (cmdp, t);
|
||||||
atomic_increment (&cmdp->cntr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cur = cmdp->cntr;
|
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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
@ -161,8 +161,11 @@ struct pthread
|
|||||||
/* Bit set if thread terminated and TCB is freed. */
|
/* Bit set if thread terminated and TCB is freed. */
|
||||||
#define TERMINATED_BIT 5
|
#define TERMINATED_BIT 5
|
||||||
#define TERMINATED_BITMASK 0x20
|
#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. */
|
/* Mask for the rest. Helps the compiler to optimize. */
|
||||||
#define CANCEL_RESTMASK 0xffffffc0
|
#define CANCEL_RESTMASK 0xffffff80
|
||||||
|
|
||||||
#define CANCEL_ENABLED_AND_CANCELED(value) \
|
#define CANCEL_ENABLED_AND_CANCELED(value) \
|
||||||
(((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK \
|
(((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK \
|
||||||
@ -185,12 +188,12 @@ struct pthread
|
|||||||
void *data;
|
void *data;
|
||||||
} specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
|
} 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. */
|
/* Two-level array for the thread-specific data. */
|
||||||
struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
|
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. */
|
/* True if events must be reported. */
|
||||||
bool report_events;
|
bool report_events;
|
||||||
|
|
||||||
@ -203,6 +206,9 @@ struct pthread
|
|||||||
/* Lock to synchronize access to the descriptor. */
|
/* Lock to synchronize access to the descriptor. */
|
||||||
lll_lock_t lock;
|
lll_lock_t lock;
|
||||||
|
|
||||||
|
/* Lock for synchronizing setxid calls. */
|
||||||
|
lll_lock_t setxid_futex;
|
||||||
|
|
||||||
#if HP_TIMING_AVAIL
|
#if HP_TIMING_AVAIL
|
||||||
/* Offset of the CPU clock at start thread start time. */
|
/* Offset of the CPU clock at start thread start time. */
|
||||||
hp_timing_t cpuclock_offset;
|
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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
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)
|
if (atomic_decrement_val (&__xidcmd->cntr) == 0)
|
||||||
lll_futex_wake (&__xidcmd->cntr, 1);
|
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))
|
if (IS_DETACHED (pd))
|
||||||
/* Free the TCB. */
|
/* Free the TCB. */
|
||||||
__free_tcb (pd);
|
__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.
|
/* 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. */
|
accessing far-away memory. */
|
||||||
iattr = &default_attr;
|
iattr = &default_attr;
|
||||||
|
|
||||||
struct pthread *pd;
|
struct pthread *pd = NULL;
|
||||||
int err = ALLOCATE_STACK (iattr, &pd);
|
int err = ALLOCATE_STACK (iattr, &pd);
|
||||||
if (__builtin_expect (err != 0, 0))
|
if (__builtin_expect (err != 0, 0))
|
||||||
/* Something went wrong. Maybe a parameter of the attributes is
|
/* Something went wrong. Maybe a parameter of the attributes is
|
||||||
|
Loading…
Reference in New Issue
Block a user