reorder timer initialization so that timer_create does not depend on free
authorRich Felker <dalias@aerifal.cx>
Wed, 30 Mar 2011 02:43:13 +0000 (22:43 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 30 Mar 2011 02:43:13 +0000 (22:43 -0400)
this allows small programs which only create times, but never delete
them, to use simple_malloc instead of the full malloc.

src/time/timer_create.c
src/time/timer_delete.c

index 1ac1906..2abec27 100644 (file)
@@ -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;
        }
 
index d7c7670..caf0489 100644 (file)
@@ -5,7 +5,7 @@ int timer_delete(timer_t t)
 {
        if (t->thread) pthread_cancel(t->thread);
        else {
-               if (t->timerid >= 0) __syscall(SYS_timer_delete, t->timerid);
+               __syscall(SYS_timer_delete, t->timerid);
                free(t);
        }
        return 0;