mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
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.
This commit is contained in:
parent
2715f28ad4
commit
5593827387
@ -1,5 +1,13 @@
|
||||
2000-06-08 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
* sysdeps/pthread/Makefile: New file. Add rules to build timer
|
||||
functionality.
|
||||
* sysdeps/unix/sysv/linux/bits/local_lim.h: Add TIMER_MAX.
|
||||
|
@ -50,6 +50,7 @@ struct thread_node
|
||||
/* Internal representation of a timer. */
|
||||
struct timer_node
|
||||
{
|
||||
pid_t creator_pid;
|
||||
struct list_links links;
|
||||
struct sigevent event;
|
||||
clockid_t clock;
|
||||
|
@ -36,7 +36,11 @@ timer_create (clock_id, evp, timerid)
|
||||
struct timer_node *newtimer = NULL;
|
||||
struct thread_node *thread = NULL;
|
||||
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
if (clock_id != CLOCK_REALTIME
|
||||
#ifdef _POSIX_CPUTIME
|
||||
&& clock_id != CLOCK_CPUTIME
|
||||
#endif
|
||||
)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -70,6 +74,7 @@ timer_create (clock_id, evp, timerid)
|
||||
}
|
||||
|
||||
newtimer->event.sigev_notify_attributes = &newtimer->attr;
|
||||
newtimer->creator_pid = getpid ();
|
||||
|
||||
switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
|
||||
{
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user