diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-06-08 20:38:08 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-06-08 20:38:08 +0000 |
commit | 559382738799bf3bef8d81c2091bd713ec8c1c9e (patch) | |
tree | 7657c43ac5a62e8d4c00bfee75ab9b4782758d05 /linuxthreads/sysdeps/pthread/timer_routines.c | |
parent | 2715f28ad4494dcf5da41398a6dbf2e43042620d (diff) | |
download | glibc-559382738799bf3bef8d81c2091bd713ec8c1c9e.tar glibc-559382738799bf3bef8d81c2091bd713ec8c1c9e.tar.gz glibc-559382738799bf3bef8d81c2091bd713ec8c1c9e.tar.bz2 glibc-559382738799bf3bef8d81c2091bd713ec8c1c9e.zip |
Update.
* sysdeps/pthread/posix-timer.h (struct timer_node): Add creator_pid.
* sysdeps/pthread/timer_create.c: Fill in creator_pid.
* sysdeps/pthread/timer_routines.c (thread_expire_timer): Send signal
with sigqueueinfo is this system call is available.
* sysdeps/pthread/timer_create.c (timer_create): Allow
CLOCK_CPUTIME if _POSIX_CPUTIME is defined.
Diffstat (limited to 'linuxthreads/sysdeps/pthread/timer_routines.c')
-rw-r--r-- | linuxthreads/sysdeps/pthread/timer_routines.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/linuxthreads/sysdeps/pthread/timer_routines.c b/linuxthreads/sysdeps/pthread/timer_routines.c index eb14643c32..cd99c9f12f 100644 --- a/linuxthreads/sysdeps/pthread/timer_routines.c +++ b/linuxthreads/sysdeps/pthread/timer_routines.c @@ -19,9 +19,13 @@ Boston, MA 02111-1307, USA. */ #include <assert.h> +#include <errno.h> #include <pthread.h> #include <stddef.h> +#include <sysdep.h> #include <time.h> +#include <unistd.h> +#include <sys/syscall.h> #include "posix-timer.h" @@ -53,6 +57,11 @@ struct list_links thread_free_list; struct list_links thread_active_list; +#ifdef __NR_rt_sigqueueinfo +extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *); +#endif + + /* List handling functions. */ static inline void list_init (struct list_links *list) @@ -222,14 +231,13 @@ __timer_thread_dealloc (struct thread_node *thread) } -/* - * Each of our threads which terminates executes this cleanup handler. We never - * terminate threads ourselves; if a thread gets here it means that the evil - * application has killed it. If the thread has timers, these require - * servicing and so we must hire a replacement thread right away. - * We must also unblock another thread that may have been waiting for - * this thread to finish servicing a timer (see timer_delete()). - */ +/* Each of our threads which terminates executes this cleanup + handler. We never terminate threads ourselves; if a thread gets here + it means that the evil application has killed it. If the thread has + timers, these require servicing and so we must hire a replacement + thread right away. We must also unblock another thread that may + have been waiting for this thread to finish servicing a timer (see + timer_delete()). */ static void thread_cleanup (void *val) @@ -272,18 +280,37 @@ thread_expire_timer (struct thread_node *self, struct timer_node *timer) pthread_mutex_unlock (&__timer_mutex); - switch (timer->event.sigev_notify) + switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL)) { case SIGEV_NONE: assert (! "timer_create should never have created such a timer"); break; case SIGEV_SIGNAL: +#ifdef __NR_rt_sigqueueinfo + { + siginfo_t info; + + /* First, clear the siginfo_t structure, so that we don't pass our + stack content to other tasks. */ + memset (&info, 0, sizeof (siginfo_t)); + /* We must pass the information about the data in a siginfo_t + value. */ + info.si_signo = timer->event.sigev_signo; + info.si_code = SI_TIMER; + info.si_pid = timer->creator_pid; + info.si_uid = getuid (); + info.si_value = timer->event.sigev_value; + + INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, info.si_signo, &info); + } +#else if (pthread_kill (self->captured, timer->event.sigev_signo) != 0) { if (pthread_kill (self->id, timer->event.sigev_signo) != 0) abort (); } +#endif break; case SIGEV_THREAD: |