]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/schedule.c
ipsec-332.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / schedule.c
index 705f4ce6437ea06a969ce7a5bea09a195bcf00a0..9907c353a83235f7a1f4992e72a4c3081b5e48a7 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
 /*     $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $       */
 
 /*
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#include <dispatch/dispatch.h>
 
 #include "misc.h"
 #include "plog.h"
 #include "schedule.h"
 #include "var.h"
 #include "gcmalloc.h"
+#include "power_mgmt.h"
+#include "localconf.h"
 
+#if !defined(__LP64__)
+// year 2038 problem and fix for 32-bit only
 #define FIXY2038PROBLEM
-
-#ifndef TAILQ_FOREACH
-#define TAILQ_FOREACH(elm, head, field) \
-        for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field))
 #endif
 
-static struct timeval timeout;
+
+extern int             terminated;
 
 #ifdef FIXY2038PROBLEM
 #define Y2038TIME_T    0x7fffffff
@@ -66,206 +70,149 @@ static time_t deltaY2038;
 
 static TAILQ_HEAD(_schedtree, sched) sctree;
 
-static void sched_add __P((struct sched *));
-static time_t current_time __P((void));
 
-/*
- * schedule handler
- * OUT:
- *     time to block until next event.
- *     if no entry, NULL returned.
- */
-struct timeval *
-schedular()
+void
+timer_handler(struct sched *sched)
 {
-       time_t now, delta;
-       struct sched *p, *next = NULL;
-
-       now = current_time();
-
-        for (p = TAILQ_FIRST(&sctree); p; p = next) {
-               /* if the entry has been dead, remove it */
-               if (p->dead)
-                       goto next_schedule;
-
-               /* if the time hasn't come, proceed to the next entry */
-               if (now < p->xtime) {
-                       next = TAILQ_NEXT(p, chain);
-                       continue;
-               }
-
-               /* mark it with dead. and call the function. */
-               p->dead = 1;
-               if (p->func != NULL)
-                       (p->func)(p->param);
-
-          next_schedule:
-               next = TAILQ_NEXT(p, chain);
-               TAILQ_REMOVE(&sctree, p, chain);
-               racoon_free(p);
-       }
-
-       p = TAILQ_FIRST(&sctree);
-       if (p == NULL)
-               return NULL;
-
-       now = current_time();
-
-       delta = p->xtime - now;
-       timeout.tv_sec = delta < 0 ? 0 : delta;
-       timeout.tv_usec = 0;
-
-       return &timeout;
+       if (slept_at || woke_at)
+        sched->dead = 1;
+   
+    TAILQ_REMOVE(&sctree, sched, chain);
+    
+    if (!sched->dead) {
+        if (sched->func != NULL && !terminated) {
+                       (sched->func)(sched->param);
+        }
+    }
+    racoon_free(sched);
 }
 
 /*
  * add new schedule to schedule table.
  */
-struct sched *
-sched_new(tick, func, param)
-       time_t tick;
-       void (*func) __P((void *));
-       void *param;
+schedule_ref
+sched_new(time_t tick, void (*func) (void *), void *param)
 {
-       static long id = 1;
-       struct sched *new;
-
-       new = (struct sched *)racoon_malloc(sizeof(*new));
-       if (new == NULL)
-               return NULL;
-
-       memset(new, 0, sizeof(*new));
-       new->func = func;
-       new->param = param;
-
-       new->id = id++;
-       time(&new->created);
-       new->tick = tick;
-
-       new->xtime = current_time() + tick;
-       new->dead = 0;
-
+    static schedule_ref next_ref = 1;
+       struct sched *new_sched;
+    
+    if (next_ref == 0)
+        next_ref++;
+    
+       new_sched = (struct sched *)racoon_malloc(sizeof(*new_sched));
+       if (new_sched == NULL)
+               return 0;
+    
+    new_sched->ref = next_ref++;
+    new_sched->dead = 0;
+       new_sched->func = func;
+       new_sched->param = param;
+    new_sched->xtime = current_time() + tick;
+    
        /* add to schedule table */
-       sched_add(new);
-
-       return(new);
-}
-
-/* add new schedule to schedule table */
-static void
-sched_add(sc)
-       struct sched *sc;
-{
-       struct sched *p;
-
-       TAILQ_FOREACH(p, &sctree, chain) {
-               if (sc->xtime < p->xtime) {
-                       TAILQ_INSERT_BEFORE(p, sc, chain);
-                       return;
-               }
-       }
-       if (p == NULL)
-               TAILQ_INSERT_TAIL(&sctree, sc, chain);
-
-       return;
+       TAILQ_INSERT_TAIL(&sctree, new_sched, chain);    
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, tick * NSEC_PER_SEC), dispatch_get_main_queue(),
+                   ^{
+                       timer_handler(new_sched);
+                   });
+    
+       return new_sched->ref;
 }
 
 /* get current time.
  * if defined FIXY2038PROBLEM, base time is the time when called sched_init().
  * Otherwise, conform to time(3).
  */
-static time_t
+time_t
 current_time()
 {
        time_t n;
 #ifdef FIXY2038PROBLEM
        time_t t;
-
+    
        time(&n);
        t = n - launched;
        if (t < 0)
                t += deltaY2038;
-
+    
        return t;
 #else
        return time(&n);
 #endif
 }
 
-void
-sched_kill(sc)
-       struct sched *sc;
+int
+sched_is_dead(schedule_ref ref)
 {
-       sc->dead = 1;
+    struct sched *sc;
+    
+    if (ref == 0)
+        return 1;
+    TAILQ_FOREACH(sc, &sctree, chain) {
+               if (sc->ref == ref) {
+            if (sc->dead)
+                return 1;
+            return 0;
+        }
+       }
+    return 1;
+}
 
-       return;
+
+int
+sched_get_time(schedule_ref ref, time_t *time)
+{
+    struct sched *sc;
+    
+    if (ref != 0) {
+        TAILQ_FOREACH(sc, &sctree, chain) {
+            if (sc->ref == ref) {
+                if (sc->dead)
+                    return 0;
+                *time = sc->xtime;
+                return 1;
+            }
+        }
+    }
+    return 0;
 }
 
-/* XXX this function is probably unnecessary. */
 void
-sched_scrub_param(param)
-       void *param;
+sched_kill(schedule_ref ref)
 {
-       struct sched *sc;
-
-       TAILQ_FOREACH(sc, &sctree, chain) {
-               if (sc->param == param) {
-                       if (!sc->dead) {
-                               plog(LLV_DEBUG, LOCATION, NULL,
-                                   "an undead schedule has been deleted.\n");
-                       }
-                       sched_kill(sc);
-               }
+    struct sched *sc;
+    
+    if (ref != 0) {
+        TAILQ_FOREACH(sc, &sctree, chain) {
+            if (sc->ref == ref) {
+                sc->dead = 1;
+                return;
+            }
+        }
        }
 }
 
-/*
- * for debug
- */
-int
-sched_dump(buf, len)
-       caddr_t *buf;
-       int *len;
+void
+sched_killall(void)
 {
-       caddr_t new;
-       struct sched *p;
-       struct scheddump *dst;
-       int cnt = 0;
-
-       /* initialize */
-       *len = 0;
-       *buf = NULL;
-
-       TAILQ_FOREACH(p, &sctree, chain)
-               cnt++;
-
-       /* no entry */
-       if (cnt == 0)
-               return -1;
-
-       *len = cnt * sizeof(*dst);
-
-       new = racoon_malloc(*len);
-       if (new == NULL)
-               return -1;
-       dst = (struct scheddump *)new;
+       struct sched *sc;
+    
+       TAILQ_FOREACH(sc, &sctree, chain)
+        sc->dead = 1;
+}
 
-        p = TAILQ_FIRST(&sctree);
-       while (p) {
-               dst->xtime = p->xtime;
-               dst->id = p->id;
-               dst->created = p->created;
-               dst->tick = p->tick;
 
-               p = TAILQ_NEXT(p, chain);
-               if (p == NULL)
-                       break;
-               dst++;
+/* XXX this function is probably unnecessary. */
+void
+sched_scrub_param(void *param)
+{
+       struct sched *sc;
+    
+       TAILQ_FOREACH(sc, &sctree, chain) {
+               if (sc->param == param) {
+                       sc->dead = 1;
+        }
        }
-
-       *buf = new;
-
-       return 0;
 }
 
 /* initialize schedule table */
@@ -274,89 +221,11 @@ sched_init()
 {
 #ifdef FIXY2038PROBLEM
        time(&launched);
-
+    
        deltaY2038 = Y2038TIME_T - launched;
 #endif
-
+    
        TAILQ_INIT(&sctree);
-
        return;
 }
 
-#ifdef STEST
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <err.h>
-
-void
-test(tick)
-       int *tick;
-{
-       printf("execute %d\n", *tick);
-       racoon_free(tick);
-}
-
-void
-getstdin()
-{
-       int *tick;
-       char buf[16];
-
-       read(0, buf, sizeof(buf));
-       if (buf[0] == 'd') {
-               struct scheddump *scbuf, *p;
-               int len;
-               sched_dump((caddr_t *)&scbuf, &len);
-               if (buf == NULL)
-                       return;
-               for (p = scbuf; len; p++) {
-                       printf("xtime=%ld\n", p->xtime);
-                       len -= sizeof(*p);
-               }
-               racoon_free(scbuf);
-               return;
-       }
-
-       tick = (int *)racoon_malloc(sizeof(*tick));
-       *tick = atoi(buf);
-       printf("new queue tick = %d\n", *tick);
-       sched_new(*tick, test, tick);
-}
-
-int
-main()
-{
-       static fd_set mask0;
-       int nfds = 0;
-       fd_set rfds;
-       struct timeval *timeout;
-       int error;
-
-       FD_ZERO(&mask0);
-       FD_SET(0, &mask0);
-       nfds = 1;
-
-       /* initialize */
-       sched_init();
-
-       while (1) {
-               rfds = mask0;
-
-               timeout = schedular();
-
-               error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout);
-               if (error < 0) {
-                       switch (errno) {
-                       case EINTR: continue;
-                       default:
-                               err(1, "select");
-                       }
-                       /*NOTREACHED*/
-               }
-
-               if (FD_ISSET(0, &rfds))
-                       getstdin();
-       }
-}
-#endif