diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-03-29 22:43:13 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-03-29 22:43:13 -0400 |
commit | 680630011d38eb9f96f92b2f080cc60f38f6df21 (patch) | |
tree | 4bf5979dc62f53126940caec7d9c44609a6d0ccc /src/time/timer_create.c | |
parent | 1c1aa32eea467b2ed43b457b5528713933b32e95 (diff) | |
download | musl-680630011d38eb9f96f92b2f080cc60f38f6df21.tar.gz musl-680630011d38eb9f96f92b2f080cc60f38f6df21.tar.xz musl-680630011d38eb9f96f92b2f080cc60f38f6df21.zip |
reorder timer initialization so that timer_create does not depend on free
this allows small programs which only create times, but never delete them, to use simple_malloc instead of the full malloc.
Diffstat (limited to 'src/time/timer_create.c')
-rw-r--r-- | src/time/timer_create.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 1ac1906b..2abec278 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -61,21 +61,28 @@ int timer_create(clockid_t clk, struct sigevent *evp, timer_t *res) struct start_args args; timer_t t; struct ksigevent ksev; + int timerid; if (evp) sev = *evp; switch (sev.sigev_notify) { case SIGEV_NONE: case SIGEV_SIGNAL: - if (!(t = calloc(1, sizeof *t))) - return -1; ksev.sigev_value = evp ? sev.sigev_value : (union sigval){.sival_ptr=t}; ksev.sigev_signo = sev.sigev_signo; ksev.sigev_notify = sev.sigev_notify; ksev.sigev_tid = 0; + if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0) + return -1; + if (!(t = calloc(1, sizeof *t))) { + syscall(SYS_timer_delete, timerid); + return -1; + } + t->timerid = timerid; break; case SIGEV_THREAD: + if (!libc.sigtimer) libc.sigtimer = sighandler; if (sev.sigev_notify_attributes) attr = *sev.sigev_notify_attributes; else @@ -95,13 +102,14 @@ int timer_create(clockid_t clk, struct sigevent *evp, timer_t *res) ksev.sigev_signo = SIGCANCEL; ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */ ksev.sigev_tid = td->tid; - if (!libc.sigtimer) libc.sigtimer = sighandler; + if (syscall(SYS_timer_create, clk, &ksev, &t->timerid) < 0) { + t->timerid = -1; + pthread_cancel(td); + return -1; + } break; - } - - t->timerid = -1; - if (syscall(SYS_timer_create, clk, &ksev, &t->timerid) < 0) { - timer_delete(t); + default: + errno = EINVAL; return -1; } |