diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-10-28 19:46:50 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-10-28 19:46:50 +0000 |
commit | f160a450c930f214f218f0c975abf188d367716f (patch) | |
tree | 110fc0d723c02447cc18d452d4886aa88f870efc /nptl | |
parent | 22c915ac42b6890383da4b1b0b63f9a15408a01c (diff) | |
download | glibc-f160a450c930f214f218f0c975abf188d367716f.tar.gz glibc-f160a450c930f214f218f0c975abf188d367716f.tar.xz glibc-f160a450c930f214f218f0c975abf188d367716f.zip |
[BZ #5204]
* crypt/sha256c-test.c: Define TIMEOUT to 6 for ancient hardware. * crypt/sha512c-test.c: Likewise.
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 16 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h | 10 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/timer_create.c | 7 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/timer_delete.c | 23 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/timer_routines.c | 45 |
5 files changed, 88 insertions, 13 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 5eabd538bc..6ea079a1b2 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,19 @@ +2007-10-28 Ulrich Drepper <drepper@redhat.com> + + [BZ #5220] + * sysdeps/unix/sysv/linux/kernel-posix-timers.h: Declare + __active_timer_sigev_thread and __active_timer_sigev_thread_lock. + (struct timer): Add next element. + * sysdeps/unix/sysv/linux/timer_create.c: For SIGEV_THREAD timers, + enqueue timer structure into __active_timer_sigev_thread list. + * sysdeps/unix/sysv/linux/timer_delete.c: For SIGEV_THREAD timers, + remove timer struct from __active_timer_sigev_thread. + * sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread): + Before using timer structure make sure it is still on the + __active_timer_sigev_thread list. Keep lock until done. + Define __active_timer_sigev_thread and + __active_timer_sigev_thread_lock. + 2007-10-27 Ulrich Drepper <drepper@redhat.com> * sysdeps/pthread/malloc-machine.h: Define ATFORK_MEM. diff --git a/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h index 3ff4cda3f4..5f419c2144 100644 --- a/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h +++ b/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -35,6 +35,11 @@ extern pthread_once_t __helper_once attribute_hidden; /* TID of the helper thread. */ extern pid_t __helper_tid attribute_hidden; +/* List of active SIGEV_THREAD timers. */ +extern struct timer *__active_timer_sigev_thread attribute_hidden; +/* Lock for the __active_timer_sigev_thread. */ +extern pthread_mutex_t __active_timer_sigev_thread_lock attribute_hidden; + /* Type of timers in the kernel. */ typedef int kernel_timer_t; @@ -57,4 +62,7 @@ struct timer void (*thrfunc) (sigval_t); sigval_t sival; pthread_attr_t attr; + + /* Next element in list of active SIGEV_THREAD timers. */ + struct timer *next; }; diff --git a/nptl/sysdeps/unix/sysv/linux/timer_create.c b/nptl/sysdeps/unix/sysv/linux/timer_create.c index 497068b554..a07234d7d1 100644 --- a/nptl/sysdeps/unix/sysv/linux/timer_create.c +++ b/nptl/sysdeps/unix/sysv/linux/timer_create.c @@ -206,6 +206,13 @@ timer_create (clock_id, evp, timerid) syscall_clockid, &sev, &newp->ktimerid); if (! INTERNAL_SYSCALL_ERROR_P (res, err)) { + /* Add to the queue of active timers with thread + delivery. */ + pthread_mutex_lock (&__active_timer_sigev_thread_lock); + newp->next = __active_timer_sigev_thread; + __active_timer_sigev_thread = newp; + pthread_mutex_unlock (&__active_timer_sigev_thread_lock); + *timerid = (timer_t) newp; return 0; } diff --git a/nptl/sysdeps/unix/sysv/linux/timer_delete.c b/nptl/sysdeps/unix/sysv/linux/timer_delete.c index 35055212a3..510541fc2a 100644 --- a/nptl/sysdeps/unix/sysv/linux/timer_delete.c +++ b/nptl/sysdeps/unix/sysv/linux/timer_delete.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -54,6 +54,27 @@ timer_delete (timerid) if (res == 0) { + if (kt->sigev_notify == SIGEV_THREAD) + { + /* Remove the timer from the list. */ + pthread_mutex_lock (&__active_timer_sigev_thread_lock); + if (__active_timer_sigev_thread == kt) + __active_timer_sigev_thread = kt->next; + else + { + struct timer *prevp = __active_timer_sigev_thread; + while (prevp->next != NULL) + if (prevp->next == kt) + { + prevp->next = kt->next; + break; + } + else + prevp = prevp->next; + } + pthread_mutex_unlock (&__active_timer_sigev_thread_lock); + } + # ifndef __ASSUME_POSIX_TIMERS /* We know the syscall support is available. */ __no_posix_timers = 1; diff --git a/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/nptl/sysdeps/unix/sysv/linux/timer_routines.c index a5eb442251..b159316fb2 100644 --- a/nptl/sysdeps/unix/sysv/linux/timer_routines.c +++ b/nptl/sysdeps/unix/sysv/linux/timer_routines.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -27,6 +27,12 @@ #include "kernel-posix-timers.h" +/* List of active SIGEV_THREAD timers. */ +struct timer *__active_timer_sigev_thread; +/* Lock for the __active_timer_sigev_thread. */ +pthread_mutex_t __active_timer_sigev_thread_lock = PTHREAD_MUTEX_INITIALIZER; + + struct thread_start_data { void (*thrfunc) (sigval_t); @@ -95,19 +101,36 @@ timer_helper_thread (void *arg) if (si.si_code == SI_TIMER) { struct timer *tk = (struct timer *) si.si_ptr; - struct thread_start_data *td = malloc (sizeof (*td)); - /* There is not much we can do if the allocation fails. */ - if (td != NULL) - { - /* That is the signal we are waiting for. */ - td->thrfunc = tk->thrfunc; - td->sival = tk->sival; + /* Check the timer is still used and will not go away + while we are reading the values here. */ + pthread_mutex_lock (&__active_timer_sigev_thread_lock); - pthread_t th; - (void) pthread_create (&th, &tk->attr, timer_sigev_thread, - td); + struct timer *runp = __active_timer_sigev_thread; + while (runp != NULL) + if (runp == tk) + break; + else + runp = runp->next; + + if (runp != NULL) + { + struct thread_start_data *td = malloc (sizeof (*td)); + + /* There is not much we can do if the allocation fails. */ + if (td != NULL) + { + /* This is the signal we are waiting for. */ + td->thrfunc = tk->thrfunc; + td->sival = tk->sival; + + pthread_t th; + (void) pthread_create (&th, &tk->attr, + timer_sigev_thread, td); + } } + + pthread_mutex_unlock (&__active_timer_sigev_thread_lock); } else if (si.si_code == SI_TKILL) /* The thread is canceled. */ |