| 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 |