diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-10-28 21:23:33 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-10-28 21:23:33 +0000 |
commit | aa5e42e3400e92ff9807cfc676d98f64c7639ef7 (patch) | |
tree | a832ef7ee39f8dee1c4502115257b1243fe5fccd /libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c | |
parent | d42a40557812cd120ce67b4633b9cbc55b20e25c (diff) | |
download | eglibc2-aa5e42e3400e92ff9807cfc676d98f64c7639ef7.tar.gz |
Merge changes between r3903 and r3996 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@3997 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c')
-rw-r--r-- | libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c index a5eb44225..b159316fb 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c +++ b/libc/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. */ |