summaryrefslogtreecommitdiff
path: root/src/time/timer_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/time/timer_create.c')
-rw-r--r--src/time/timer_create.c24
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;
}