1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00
This commit is contained in:
Jakub Jelinek
2007-07-12 18:26:36 +00:00
parent 7d58530341
commit 0ecb606cb6
6215 changed files with 494638 additions and 305010 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@ -27,6 +27,13 @@
#include "kernel-posix-timers.h"
struct thread_start_data
{
void (*thrfunc) (sigval_t);
sigval_t sival;
};
#ifdef __NR_timer_create
/* Helper thread to call the user-provided function. */
static void *
@ -40,10 +47,16 @@ timer_sigev_thread (void *arg)
INTERNAL_SYSCALL_DECL (err);
INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
struct timer *tk = (struct timer *) arg;
struct thread_start_data *td = (struct thread_start_data *) arg;
void (*thrfunc) (sigval_t) = td->thrfunc;
sigval_t sival = td->sival;
/* The TD object was allocated in timer_helper_thread. */
free (td);
/* Call the user-provided function. */
tk->thrfunc (tk->sival);
thrfunc (sival);
return NULL;
}
@ -53,10 +66,11 @@ timer_sigev_thread (void *arg)
static void *
timer_helper_thread (void *arg)
{
/* Wait for the SIGTIMER signal and none else. */
/* Wait for the SIGTIMER signal, allowing the setXid signal, and
none else. */
sigset_t ss;
sigemptyset (&ss);
sigaddset (&ss, SIGTIMER);
__sigaddset (&ss, SIGTIMER);
/* Endless loop of waiting for signals. The loop is only ended when
the thread is canceled. */
@ -81,10 +95,19 @@ 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));
/* That the signal we are waiting for. */
pthread_t th;
(void) pthread_create (&th, &tk->attr, timer_sigev_thread, tk);
/* 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;
pthread_t th;
(void) pthread_create (&th, &tk->attr, timer_sigev_thread,
td);
}
}
else if (si.si_code == SI_TKILL)
/* The thread is canceled. */
@ -121,10 +144,11 @@ __start_helper_thread (void)
(void) pthread_attr_init (&attr);
(void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
/* Block all signals in the helper thread. To do this thoroughly we
temporarily have to block all signals here. The helper can lose
wakeups if SIGCANCEL is not blocked throughout, but sigfillset omits
it. So, we add it back explicitly here. */
/* Block all signals in the helper thread but SIGSETXID. To do this
thoroughly we temporarily have to block all signals here. The
helper can lose wakeups if SIGCANCEL is not blocked throughout,
but sigfillset omits it SIGSETXID. So, we add SIGCANCEL back
explicitly here. */
sigset_t ss;
sigset_t oss;
sigfillset (&ss);