aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2020-10-14 19:07:27 -0400
committerRich Felker <dalias@aerifal.cx>2020-10-14 20:27:12 -0400
commit85e16aec51c343f64601b70a6081def69b9f87bc (patch)
treed802c54aba2c459c46dd1eba4f5d8e78d3c5fcd8
parent6ae2568bc2367b4d47e0ea1cb043fd56e697912f (diff)
downloadmusl-85e16aec51c343f64601b70a6081def69b9f87bc.zip
musl-85e16aec51c343f64601b70a6081def69b9f87bc.tar.gz
musl-85e16aec51c343f64601b70a6081def69b9f87bc.tar.bz2
drop use of pthread_once in timer_create
this makes the code slightly smaller and eliminates timer_create from relevance to possible future changes to multithreaded fork. the barrier of a_store isn't technically needed here, but a_store is used anyway for internal consistency of the memory model.
-rw-r--r--src/time/timer_create.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/src/time/timer_create.c b/src/time/timer_create.c
index 2b1ea17..5ddfda2 100644
--- a/src/time/timer_create.c
+++ b/src/time/timer_create.c
@@ -2,6 +2,7 @@
#include <setjmp.h>
#include <limits.h>
#include "pthread_impl.h"
+#include "atomic.h"
struct ksigevent {
union sigval sigev_value;
@@ -32,14 +33,6 @@ static void cleanup_fromsig(void *p)
longjmp(p, 1);
}
-static void install_handler()
-{
- struct sigaction sa = {
- .sa_handler = SIG_DFL,
- };
- __libc_sigaction(SIGTIMER, &sa, 0);
-}
-
static void *start(void *arg)
{
pthread_t self = __pthread_self();
@@ -66,7 +59,7 @@ static void *start(void *arg)
int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
{
- static pthread_once_t once = PTHREAD_ONCE_INIT;
+ volatile static int init = 0;
pthread_t td;
pthread_attr_t attr;
int r;
@@ -90,7 +83,11 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
*res = (void *)(intptr_t)timerid;
break;
case SIGEV_THREAD:
- pthread_once(&once, install_handler);
+ if (!init) {
+ struct sigaction sa = { .sa_handler = SIG_DFL };
+ __libc_sigaction(SIGTIMER, &sa, 0);
+ a_store(&init, 1);
+ }
if (evp->sigev_notify_attributes)
attr = *evp->sigev_notify_attributes;
else