diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-06-25 10:51:31 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-06-25 12:21:12 +0200 |
commit | 2c16cb88a6e5ace0fb7cedca86860ea7bde522a7 (patch) | |
tree | 8e7aa16a33590ccd27050ef3d3b00607b7f15751 /sysdeps/unix/sysv/linux/timer_routines.c | |
parent | 1a5a653be2f95d4d9485d08672dc5083c74c39d8 (diff) | |
download | glibc-2c16cb88a6e5ace0fb7cedca86860ea7bde522a7.tar.gz glibc-2c16cb88a6e5ace0fb7cedca86860ea7bde522a7.tar.xz glibc-2c16cb88a6e5ace0fb7cedca86860ea7bde522a7.zip |
Linux: Move timer helper routines from librt to libc
This adds several temporary GLIBC_PRIVATE exports. The symbol names are changed so that they all start with __timer_. It is now possible to invoke the fork handler directly, so pthread_atfork is no longer necessary. The associated error cannot happen anymore, and cancellation handling can be removed from the helper thread routine. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps/unix/sysv/linux/timer_routines.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/timer_routines.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c index 4098da8a5f..e0bb169370 100644 --- a/sysdeps/unix/sysv/linux/timer_routines.c +++ b/sysdeps/unix/sysv/linux/timer_routines.c @@ -26,10 +26,13 @@ /* 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 timer *__timer_active_sigev_thread __attribute__ ((nocommon)); +libc_hidden_data_def (__timer_active_sigev_thread) +/* Lock for _timer_active_sigev_thread. */ +pthread_mutex_t __timer_active_sigev_thread_lock __attribute__ ((nocommon)) + = PTHREAD_MUTEX_INITIALIZER; +libc_hidden_data_def (__timer_active_sigev_thread_lock) struct thread_start_data { @@ -59,7 +62,7 @@ timer_sigev_thread (void *arg) /* Helper function to support starting threads for SIGEV_THREAD. */ -static void * +static _Noreturn void * timer_helper_thread (void *arg) { /* Endless loop of waiting for signals. The loop is only ended when @@ -68,16 +71,16 @@ timer_helper_thread (void *arg) { siginfo_t si; - while (sigwaitinfo (&sigtimer_set, &si) < 0); + while (__sigwaitinfo (&sigtimer_set, &si) < 0); if (si.si_code == SI_TIMER) { struct timer *tk = (struct timer *) si.si_ptr; /* 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_mutex_lock (&__timer_active_sigev_thread_lock); - struct timer *runp = __active_timer_sigev_thread; + struct timer *runp = __timer_active_sigev_thread; while (runp != NULL) if (runp == tk) break; @@ -96,45 +99,44 @@ timer_helper_thread (void *arg) td->sival = tk->sival; pthread_t th; - pthread_create (&th, &tk->attr, timer_sigev_thread, td); + __pthread_create (&th, &tk->attr, timer_sigev_thread, td); } } - pthread_mutex_unlock (&__active_timer_sigev_thread_lock); + __pthread_mutex_unlock (&__timer_active_sigev_thread_lock); } - else if (si.si_code == SI_TKILL) - /* The thread is canceled. */ - pthread_exit (NULL); } } /* Control variable for helper thread creation. */ -pthread_once_t __helper_once attribute_hidden; +pthread_once_t __timer_helper_once __attribute__ ((nocommon)) + = PTHREAD_ONCE_INIT; +libc_hidden_data_def (__timer_helper_once) /* TID of the helper thread. */ -pid_t __helper_tid attribute_hidden; +pid_t __timer_helper_tid __attribute__ ((nocommon)); +libc_hidden_data_def (__timer_helper_tid) /* Reset variables so that after a fork a new helper thread gets started. */ -static void -reset_helper_control (void) +void +__timer_fork_subprocess (void) { - __helper_once = PTHREAD_ONCE_INIT; - __helper_tid = 0; + __timer_helper_once = PTHREAD_ONCE_INIT; + __timer_helper_tid = 0; } void -attribute_hidden -__start_helper_thread (void) +__timer_start_helper_thread (void) { /* The helper thread needs only very little resources and should go away automatically when canceled. */ pthread_attr_t attr; - (void) pthread_attr_init (&attr); - (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr)); + __pthread_attr_init (&attr); + __pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr)); /* Block all signals in the helper thread but SIGSETXID. */ sigset_t ss; @@ -143,21 +145,18 @@ __start_helper_thread (void) int res = __pthread_attr_setsigmask_internal (&attr, &ss); if (res != 0) { - pthread_attr_destroy (&attr); + __pthread_attr_destroy (&attr); return; } /* Create the helper thread for this timer. */ pthread_t th; - res = pthread_create (&th, &attr, timer_helper_thread, NULL); + res = __pthread_create (&th, &attr, timer_helper_thread, NULL); if (res == 0) /* We managed to start the helper thread. */ - __helper_tid = ((struct pthread *) th)->tid; + __timer_helper_tid = ((struct pthread *) th)->tid; /* No need for the attribute anymore. */ - (void) pthread_attr_destroy (&attr); - - /* We have to make sure that after fork()ing a new helper thread can - be created. */ - pthread_atfork (NULL, NULL, reset_helper_control); + __pthread_attr_destroy (&attr); } +libc_hidden_def (__timer_start_helper_thread) |