... | ... |
@@ -55,10 +55,13 @@ CC=gcc |
55 | 55 |
LD=gcc |
56 | 56 |
|
57 | 57 |
ifeq ($(mode), release) |
58 |
- CFLAGS=-O2 -fPIC -DPIC -Wcast-align $(PROFILE) -Winline#-Wmissing-prototypes |
|
58 |
+ CFLAGS=-O2 -Wcast-align $(PROFILE) -Winline#-Wmissing-prototypes |
|
59 | 59 |
LDFLAGS=-Wl,-O2 -Wl,-E $(PROFILE) |
60 |
+ # we need -fPIC -DPIC only for shared objects, we don't need them for the |
|
61 |
+ # executable file, because it's always loaded at a fixed address |
|
62 |
+ # -andrei |
|
60 | 63 |
else |
61 |
- CFLAGS=-g -fPIC -DPIC -Wcast-align -Winline |
|
64 |
+ CFLAGS=-g -Wcast-align -Winline |
|
62 | 65 |
LDFLAGS=-g -Wl,-E |
63 | 66 |
endif |
64 | 67 |
|
... | ... |
@@ -28,6 +28,7 @@ |
28 | 28 |
#include "shm_mem.h" |
29 | 29 |
#endif |
30 | 30 |
#include "sr_module.h" |
31 |
+#include "timer.h" |
|
31 | 32 |
|
32 | 33 |
|
33 | 34 |
#include <signal.h> |
... | ... |
@@ -230,6 +231,22 @@ int main_loop() |
230 | 231 |
#endif |
231 | 232 |
/* only one address */ |
232 | 233 |
if (udp_init(addresses[0],port_no)==-1) goto error; |
234 |
+ |
|
235 |
+ /* we need another process to act as the timer*/ |
|
236 |
+ if (timer_list){ |
|
237 |
+ if ((pid=fork())<0){ |
|
238 |
+ LOG(L_CRIT, "main_loop: Cannot fork\n"); |
|
239 |
+ goto error; |
|
240 |
+ } |
|
241 |
+ if (pid==0){ |
|
242 |
+ /* child */ |
|
243 |
+ /* timer!*/ |
|
244 |
+ for(;;){ |
|
245 |
+ sleep(TIMER_TICK); |
|
246 |
+ timer_ticker(); |
|
247 |
+ } |
|
248 |
+ } |
|
249 |
+ } |
|
233 | 250 |
/* receive loop */ |
234 | 251 |
udp_rcv_loop(); |
235 | 252 |
}else{ |
... | ... |
@@ -252,11 +269,16 @@ int main_loop() |
252 | 269 |
close(udp_sock); /*parent*/ |
253 | 270 |
} |
254 | 271 |
} |
255 |
- |
|
256 |
- for(;;){ |
|
257 |
- /* debug: instead of doing something usefull */ |
|
258 |
- /* (placeholder for timers, etc.) */ |
|
259 |
- sleep(10); |
|
272 |
+ if (timer_list){ |
|
273 |
+ for(;;){ |
|
274 |
+ /* debug: instead of doing something usefull */ |
|
275 |
+ /* (placeholder for timers, etc.) */ |
|
276 |
+ sleep(TIMER_TICK); |
|
277 |
+ /* if we received a signal => TIMER_TICK may have not elapsed*/ |
|
278 |
+ timer_ticker(); |
|
279 |
+ } |
|
280 |
+ }else{ |
|
281 |
+ for(;;) sleep(LONG_SLEEP); |
|
260 | 282 |
} |
261 | 283 |
|
262 | 284 |
return 0; |
... | ... |
@@ -309,8 +331,9 @@ static void sig_usr(int signo) |
309 | 331 |
#endif |
310 | 332 |
} |
311 | 333 |
} |
312 |
- |
|
313 |
- |
|
334 |
+ |
|
335 |
+ |
|
336 |
+ |
|
314 | 337 |
int main(int argc, char** argv) |
315 | 338 |
{ |
316 | 339 |
|
... | ... |
@@ -332,6 +355,7 @@ int main(int argc, char** argv) |
332 | 355 |
goto error; |
333 | 356 |
} |
334 | 357 |
|
358 |
+ |
|
335 | 359 |
/* process command line (get port no, cfg. file path etc) */ |
336 | 360 |
opterr=0; |
337 | 361 |
options= |
... | ... |
@@ -543,7 +567,6 @@ int main(int argc, char** argv) |
543 | 567 |
if ( daemonize(argv[0]) <0 ) goto error; |
544 | 568 |
} |
545 | 569 |
|
546 |
- |
|
547 | 570 |
return main_loop(); |
548 | 571 |
|
549 | 572 |
|
550 | 573 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,69 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ */ |
|
4 |
+ |
|
5 |
+#include "timer.h" |
|
6 |
+#include "dprint.h" |
|
7 |
+#include "error.h" |
|
8 |
+#include "config.h" |
|
9 |
+ |
|
10 |
+#include <stdlib.h> |
|
11 |
+ |
|
12 |
+ |
|
13 |
+struct sr_timer* timer_list=0; |
|
14 |
+ |
|
15 |
+static int jiffies=0; |
|
16 |
+static int timer_id=0; |
|
17 |
+ |
|
18 |
+/*register a periodic timer; |
|
19 |
+ * ret: <0 on error*/ |
|
20 |
+int register_timer(timer_function f, void* param, unsigned int interval) |
|
21 |
+{ |
|
22 |
+ struct sr_timer* t; |
|
23 |
+ |
|
24 |
+ t=malloc(sizeof(struct sr_timer)); |
|
25 |
+ if (t==0){ |
|
26 |
+ LOG(L_ERR, "ERROR: register_timer: out of memory\n"); |
|
27 |
+ goto error; |
|
28 |
+ } |
|
29 |
+ t->id=timer_id++; |
|
30 |
+ t->timer_f=f; |
|
31 |
+ t->t_param=param; |
|
32 |
+ t->interval=interval; |
|
33 |
+ t->expires=jiffies+interval; |
|
34 |
+ /* insert it into the list*/ |
|
35 |
+ t->next=timer_list; |
|
36 |
+ timer_list=t; |
|
37 |
+ return t->id; |
|
38 |
+ |
|
39 |
+error: |
|
40 |
+ return E_OUT_OF_MEM; |
|
41 |
+} |
|
42 |
+ |
|
43 |
+ |
|
44 |
+ |
|
45 |
+void timer_ticker() |
|
46 |
+{ |
|
47 |
+ struct sr_timer* t; |
|
48 |
+ unsigned int prev_jiffies; |
|
49 |
+ |
|
50 |
+ prev_jiffies=jiffies; |
|
51 |
+ jiffies+=TIMER_TICK; |
|
52 |
+ /* test for overflow (if tick= 1s =>overflow in 136 years)*/ |
|
53 |
+ if (jiffies<prev_jiffies){ |
|
54 |
+ /*force expire & update every timer, a little buggy but it |
|
55 |
+ * happens once in 136 years :) */ |
|
56 |
+ for(t=timer_list;t;t=t->next){ |
|
57 |
+ t->expires=jiffies+t->interval; |
|
58 |
+ t->timer_f(jiffies, t->t_param); |
|
59 |
+ } |
|
60 |
+ return; |
|
61 |
+ } |
|
62 |
+ |
|
63 |
+ for (t=timer_list;t; t=t->next){ |
|
64 |
+ if (jiffies>=t->expires){ |
|
65 |
+ t->expires=jiffies+t->interval; |
|
66 |
+ t->timer_f(jiffies, t->t_param); |
|
67 |
+ } |
|
68 |
+ } |
|
69 |
+} |
0 | 70 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,37 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ * |
|
5 |
+ * timer related functions |
|
6 |
+ */ |
|
7 |
+ |
|
8 |
+ |
|
9 |
+#ifndef timer_h |
|
10 |
+#define timer_h |
|
11 |
+ |
|
12 |
+typedef void (timer_function)(unsigned int ticks, void* param); |
|
13 |
+ |
|
14 |
+ |
|
15 |
+struct sr_timer{ |
|
16 |
+ int id; |
|
17 |
+ timer_function* timer_f; |
|
18 |
+ void* t_param; |
|
19 |
+ unsigned int interval; |
|
20 |
+ |
|
21 |
+ unsigned int expires; |
|
22 |
+ |
|
23 |
+ struct sr_timer* next; |
|
24 |
+}; |
|
25 |
+ |
|
26 |
+ |
|
27 |
+ |
|
28 |
+extern struct sr_timer* timer_list; |
|
29 |
+ |
|
30 |
+ |
|
31 |
+ |
|
32 |
+/*register a periodic timer; |
|
33 |
+ * ret: <0 on errror*/ |
|
34 |
+int register_timer(timer_function f, void* param, unsigned int interval); |
|
35 |
+void timer_ticker(); |
|
36 |
+ |
|
37 |
+#endif |