OLD | NEW |
1 /* | 1 /* |
2 * dhcpcd - DHCP client daemon | 2 * dhcpcd - DHCP client daemon |
3 * Copyright (c) 2006-2008 Roy Marples <roy@marples.name> | 3 * Copyright (c) 2006-2008 Roy Marples <roy@marples.name> |
4 * All rights reserved | 4 * All rights reserved |
5 | 5 |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include <stdlib.h> | 34 #include <stdlib.h> |
35 #include <syslog.h> | 35 #include <syslog.h> |
36 | 36 |
37 #include "common.h" | 37 #include "common.h" |
38 #include "eloop.h" | 38 #include "eloop.h" |
39 | 39 |
40 static struct timeval now; | 40 static struct timeval now; |
41 | 41 |
42 static struct event { | 42 static struct event { |
43 int fd; | 43 int fd; |
| 44 int flags; |
44 void (*callback)(void *); | 45 void (*callback)(void *); |
| 46 void (*callback_f)(int, void *); |
45 void *arg; | 47 void *arg; |
46 struct event *next; | 48 struct event *next; |
47 } *events; | 49 } *events; |
48 static struct event *free_events; | 50 static struct event *free_events; |
49 | 51 |
50 static struct timeout { | 52 static struct timeout { |
51 struct timeval when; | 53 struct timeval when; |
52 void (*callback)(void *); | 54 void (*callback)(void *); |
53 void *arg; | 55 void *arg; |
54 struct timeout *next; | 56 struct timeout *next; |
55 } *timeouts; | 57 } *timeouts; |
56 static struct timeout *free_timeouts; | 58 static struct timeout *free_timeouts; |
57 | 59 |
58 static struct pollfd *fds; | 60 static struct pollfd *fds; |
59 static size_t fds_len; | 61 static size_t fds_len; |
60 | 62 |
61 void | 63 static int |
62 add_event(int fd, void (*callback)(void *), void *arg) | 64 _add_event_flags(int fd, |
| 65 int flags, |
| 66 void (*callback)(void *), |
| 67 void (*callback_f)(int, void *), |
| 68 void *arg) |
63 { | 69 { |
64 struct event *e, *last = NULL; | 70 struct event *e, *last = NULL; |
65 | 71 |
66 /* We should only have one callback monitoring the fd */ | 72 /* We should only have one callback monitoring the fd */ |
67 for (e = events; e; e = e->next) { | 73 for (e = events; e; e = e->next) { |
68 if (e->fd == fd) { | 74 if (e->fd == fd) { |
| 75 e->flags = flags; |
69 e->callback = callback; | 76 e->callback = callback; |
| 77 e->callback_f = callback_f; |
70 e->arg = arg; | 78 e->arg = arg; |
71 » » » return; | 79 » » » return 0; |
72 } | 80 } |
73 last = e; | 81 last = e; |
74 } | 82 } |
75 | 83 |
76 /* Allocate a new event if no free ones already allocated */ | 84 /* Allocate a new event if no free ones already allocated */ |
77 if (free_events) { | 85 if (free_events) { |
78 e = free_events; | 86 e = free_events; |
79 free_events = e->next; | 87 free_events = e->next; |
80 » } else | 88 » } else { |
81 » » e = xmalloc(sizeof(*e)); | 89 » » e = malloc(sizeof(*e)); |
| 90 » » if (e == NULL) |
| 91 » » » return -1; |
| 92 » } |
82 e->fd = fd; | 93 e->fd = fd; |
| 94 e->flags = flags; |
83 e->callback = callback; | 95 e->callback = callback; |
| 96 e->callback_f = callback_f; |
84 e->arg = arg; | 97 e->arg = arg; |
85 e->next = NULL; | 98 e->next = NULL; |
86 if (last) | 99 if (last) |
87 last->next = e; | 100 last->next = e; |
88 else | 101 else |
89 events = e; | 102 events = e; |
| 103 return 0; |
| 104 } |
| 105 |
| 106 int |
| 107 add_event(int fd, void (*callback)(void *), void *arg) |
| 108 { |
| 109 return _add_event_flags(fd, 0, callback, NULL, arg); |
| 110 } |
| 111 |
| 112 int |
| 113 add_event_flags(int fd, int flags, void (*callback)(int, void *), void *arg) |
| 114 { |
| 115 return _add_event_flags(fd, flags, NULL, callback, arg); |
90 } | 116 } |
91 | 117 |
92 void | 118 void |
93 delete_event(int fd) | 119 delete_event(int fd) |
94 { | 120 { |
95 struct event *e, *last = NULL; | 121 struct event *e, *last = NULL; |
96 | 122 |
97 for (e = events; e; e = e->next) { | 123 for (e = events; e; e = e->next) { |
98 if (e->fd == fd) { | 124 if (e->fd == fd) { |
99 if (last) | 125 if (last) |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 free_timeouts = t; | 315 free_timeouts = t; |
290 continue; | 316 continue; |
291 } | 317 } |
292 timersub(&timeouts->when, &now, &tv); | 318 timersub(&timeouts->when, &now, &tv); |
293 if (tv.tv_sec > INT_MAX / 1000 || | 319 if (tv.tv_sec > INT_MAX / 1000 || |
294 (tv.tv_sec == INT_MAX / 1000 && | 320 (tv.tv_sec == INT_MAX / 1000 && |
295 (tv.tv_usec + 999) / 1000 > INT_MAX % 1000)) | 321 (tv.tv_usec + 999) / 1000 > INT_MAX % 1000)) |
296 msecs = INT_MAX; | 322 msecs = INT_MAX; |
297 else | 323 else |
298 msecs = tv.tv_sec * 1000 + | 324 msecs = tv.tv_sec * 1000 + |
299 » » » » (tv.tv_usec + 999) / 1000; | 325 » » » » » (tv.tv_usec + 999) / 1000; |
300 } else | 326 } else |
301 /* No timeouts, so wait forever. */ | 327 /* No timeouts, so wait forever. */ |
302 msecs = -1; | 328 msecs = -1; |
303 | 329 |
304 /* Allocate memory for our pollfds as and when needed. | 330 /* Allocate memory for our pollfds as and when needed. |
305 * We don't bother shrinking it. */ | 331 * We don't bother shrinking it. */ |
306 nfds = 0; | 332 nfds = 0; |
307 for (e = events; e; e = e->next) | 333 for (e = events; e; e = e->next) |
308 nfds++; | 334 nfds++; |
309 if (msecs == -1 && nfds == 0) { | 335 if (msecs == -1 && nfds == 0) { |
310 syslog(LOG_ERR, "nothing to do"); | 336 syslog(LOG_ERR, "nothing to do"); |
311 exit(EXIT_FAILURE); | 337 exit(EXIT_FAILURE); |
312 } | 338 } |
313 if (nfds > fds_len) { | 339 if (nfds > fds_len) { |
314 free(fds); | 340 free(fds); |
315 » » » /* Allocate 5 more than we need for future use */ | 341 » » » fds = malloc(sizeof(*fds) * nfds); |
316 » » » fds_len = nfds + 5; | 342 » » » if (fds == NULL) { |
317 » » » fds = xmalloc(sizeof(*fds) * fds_len); | 343 » » » » syslog(LOG_ERR, "malloc: %m"); |
| 344 » » » » exit(EXIT_FAILURE); |
| 345 » » » } |
| 346 » » » fds_len = nfds; |
318 } | 347 } |
319 nfds = 0; | 348 nfds = 0; |
320 for (e = events; e; e = e->next) { | 349 for (e = events; e; e = e->next) { |
321 fds[nfds].fd = e->fd; | 350 fds[nfds].fd = e->fd; |
322 » » » fds[nfds].events = POLLIN; | 351 » » » if (e->flags == 0) |
| 352 » » » » fds[nfds].events = POLLIN; |
| 353 » » » else |
| 354 » » » » fds[nfds].events = e->flags; |
323 fds[nfds].revents = 0; | 355 fds[nfds].revents = 0; |
324 nfds++; | 356 nfds++; |
325 } | 357 } |
326 n = poll(fds, nfds, msecs); | 358 n = poll(fds, nfds, msecs); |
327 if (n == -1) { | 359 if (n == -1) { |
328 if (errno == EAGAIN || errno == EINTR) { | 360 if (errno == EAGAIN || errno == EINTR) { |
329 get_monotonic(&now); | 361 get_monotonic(&now); |
330 continue; | 362 continue; |
331 } | 363 } |
332 syslog(LOG_ERR, "poll: %m"); | 364 syslog(LOG_ERR, "poll: %m"); |
333 exit(EXIT_FAILURE); | 365 exit(EXIT_FAILURE); |
334 } | 366 } |
335 | 367 |
336 /* Get the now time and process any triggered events. */ | 368 /* Get the now time and process any triggered events. */ |
337 get_monotonic(&now); | 369 get_monotonic(&now); |
338 if (n == 0) | 370 if (n == 0) |
339 continue; | 371 continue; |
340 for (i = 0; i < nfds; i++) { | 372 for (i = 0; i < nfds; i++) { |
341 » » » if (!(fds[i].revents & (POLLIN | POLLHUP))) | 373 » » » if (fds[i].revents == 0) |
342 continue; | 374 continue; |
343 for (e = events; e; e = e->next) { | 375 for (e = events; e; e = e->next) { |
344 » » » » if (e->fd == fds[i].fd) { | 376 » » » » if (e->fd != fds[i].fd) |
345 » » » » » e->callback(e->arg); | 377 » » » » » continue; |
| 378 » » » » if (e->flags) { |
| 379 » » » » » e->callback_f(fds[i].revents, e->arg); |
346 break; | 380 break; |
347 } | 381 } |
| 382 if (fds[i].revents & (POLLIN | POLLHUP)) |
| 383 e->callback(e->arg); |
| 384 break; |
348 } | 385 } |
349 } | 386 } |
350 } | 387 } |
351 } | 388 } |
OLD | NEW |