usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / xl2tpd / scheduler.c
blobd19b77cebde75939583657e780db28e8bf4381af
1 /*
2 * Layer Two Tunnelling Protocol Daemon
3 * Copyright (C) 1998 Adtran, Inc.
4 * Copyright (C) 2002 Jeff McAdams
6 * Mark Spencer
8 * This software is distributed under the terms
9 * of the GPL, which you should have received
10 * along with this source.
12 * Scheduler code for time based functionality
16 #include <stdlib.h>
17 #include <string.h>
18 #include "l2tp.h"
19 #include "scheduler.h"
21 struct schedule_entry *events;
23 void init_scheduler (void)
25 events = NULL;
28 struct timeval *process_schedule (struct timeval *ptv)
30 /* Check queue for events which should be
31 executed right now. Execute them, then
32 see how long we should set the next timer
34 struct schedule_entry *p = events;
35 struct timeval now;
36 struct timeval then;
37 while (events)
39 gettimeofday (&now, NULL);
40 p = events;
41 if (TVLESSEQ (p->tv, now))
43 events = events->next;
44 /* This needs to be executed, as it has expired.
45 It is expected that p->func will free p->data
46 if it is necessary */
47 (*p->func) (p->data);
48 free (p);
50 else
51 break;
53 /* When we get here, either there are no more events
54 in the queue, or the remaining events need to happen
55 in the future, so we should schedule another alarm */
56 if (events)
58 then.tv_sec = events->tv.tv_sec - now.tv_sec;
59 then.tv_usec = events->tv.tv_usec - now.tv_usec;
60 if (then.tv_usec < 0)
62 then.tv_sec -= 1;
63 then.tv_usec += 1000000;
65 if ((then.tv_sec <= 0) && (then.tv_usec <= 0))
67 l2tp_log (LOG_WARNING, "%s: Whoa... Scheduling for <=0 time???\n",
68 __FUNCTION__);
69 then.tv_sec = 1;
70 then.tv_usec = 0;
72 *ptv = then;
73 return ptv;
75 else
77 return NULL;
81 struct schedule_entry *schedule (struct timeval tv, void (*func) (void *),
82 void *data)
84 /* Schedule func to be run at relative time tv with data
85 as arguments. If it has already expired, run it
86 immediately. The queue should be in order of
87 increasing time */
88 struct schedule_entry *p = events, *q = NULL;
89 struct timeval diff;
90 diff = tv;
91 gettimeofday (&tv, NULL);
92 tv.tv_sec += diff.tv_sec;
93 tv.tv_usec += diff.tv_usec;
94 if (tv.tv_usec > 1000000)
96 tv.tv_sec++;
97 tv.tv_usec -= 1000000;
99 while (p)
101 if (TVLESS (tv, p->tv))
102 break;
103 q = p;
104 p = p->next;
106 if (q)
108 q->next =
109 (struct schedule_entry *) malloc (sizeof (struct schedule_entry));
110 q = q->next;
112 else
114 q = (struct schedule_entry *) malloc (sizeof (struct schedule_entry));
115 events = q;
117 q->tv = tv;
118 q->func = func;
119 q->data = data;
120 q->next = p;
121 return q;
125 inline struct schedule_entry *aschedule (struct timeval tv,
126 void (*func) (void *), void *data)
128 /* Schedule func to be run at absolute time tv in the future with data
129 as arguments */
130 struct timeval now;
131 gettimeofday (&now, NULL);
132 tv.tv_usec -= now.tv_usec;
133 if (tv.tv_usec < 0)
135 tv.tv_usec += 1000000;
136 tv.tv_sec--;
138 tv.tv_sec -= now.tv_sec;
139 return schedule (tv, func, data);
142 void deschedule (struct schedule_entry *s)
144 struct schedule_entry *p = events, *q = NULL;
145 if (!s)
146 return;
147 while (p)
149 if (p == s)
151 if (q)
153 q->next = p->next;
155 else
157 events = events->next;
159 free (p);
160 break;
162 q = p;
163 p = p->next;