25 RCSID(
"$Id: c1cc9a02193f7c8d69ce4114fdf5c92f899bde41 $")
27 #include <freeradius-devel/libradius.h>
28 #include <freeradius-devel/heap.h>
29 #include <freeradius-devel/event.h>
32 #ifndef HAVE_SYS_EVENT_H
33 #error kqueue requires <sys/event.h>
36 #include <sys/event.h>
46 #define FR_EV_MAX_FDS (256)
49 #define USEC (1000000)
91 if (a->
when.tv_sec < b->
when.tv_sec)
return -1;
92 if (a->
when.tv_sec > b->
when.tv_sec)
return +1;
94 if (a->
when.tv_usec < b->
when.tv_usec)
return -1;
95 if (a->
when.tv_usec > b->
when.tv_usec)
return +1;
178 if (!el || !parent || !*parent)
return 0;
184 ev = talloc_get_type_abort(*parent,
fr_event_t);
219 if (!when || (when->tv_usec >=
USEC)) {
237 ev = talloc_get_type_abort(*parent,
fr_event_t);
245 memset(ev, 0,
sizeof(*ev));
290 if ((ev->
when.tv_sec > when->tv_sec) ||
291 ((ev->
when.tv_sec == when->tv_sec) &&
292 (ev->
when.tv_usec > when->tv_usec))) {
317 gettimeofday(when, NULL);
381 j = (i + fd) & (FR_EV_MAX_FDS - 1);
388 EV_SET(&evset, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, &el->
readers[j]);
389 if (kevent(el->kq, &evset, 1, NULL, 0, NULL) < 0) {
448 if (!el || (fd < 0))
return 0;
450 if (type != 0)
return 0;
457 j = (i + fd) & (FR_EV_MAX_FDS - 1);
468 EV_SET(&evset, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
469 (void) kevent(el->kq, &evset, 1, NULL, 0, NULL);
504 return (el->
exit != 0);
510 struct timeval when, *wake;
512 struct timespec ts_when, *ts_wake;
515 fd_set read_fds, master_fds;
529 #ifdef __clang_analyzer__
530 memset(&master_fds, 0,
sizeof(master_fds));
532 FD_ZERO(&master_fds);
562 gettimeofday(&el->
now, NULL);
564 if (timercmp(&el->
now, &ev->
when, <)) {
566 when.tv_sec -= el->
now.tv_sec;
568 if (when.tv_sec > 0) {
570 when.tv_usec +=
USEC;
574 when.tv_usec -= el->
now.tv_usec;
575 if (when.tv_usec >=
USEC) {
576 when.tv_usec -=
USEC;
595 read_fds = master_fds;
596 rcode = select(maxfd + 1, &read_fds, NULL, NULL, wake);
597 if ((rcode < 0) && (errno != EINTR)) {
607 ts_when.tv_sec = when.tv_sec;
608 ts_when.tv_nsec = when.tv_usec * 1000;
613 rcode = kevent(el->kq, NULL, 0, el->events,
FR_EV_MAX_FDS, ts_wake);
618 gettimeofday(&el->
now, NULL);
623 if (rcode <= 0)
continue;
633 if (ef->
fd < 0)
continue;
635 if (!FD_ISSET(ef->
fd, &read_fds))
continue;
647 for (i = 0; i < rcode; i++) {
650 if (el->events[i].flags & EV_EOF) {
696 static void print_time(
void *ctx)
698 struct timeval *when = ctx;
700 printf(
"%d.%06d\n", when->tv_sec, when->tv_usec);
706 static uint32_t event_rand(
void)
711 if (rand_pool.
randcnt == 256) {
721 int main(
int argc,
char **argv)
724 struct timeval array[MAX];
725 struct timeval now, when;
731 memset(&rand_pool, 0,
sizeof(rand_pool));
732 rand_pool.
randrsl[1] = time(NULL);
737 gettimeofday(&array[0], NULL);
738 for (i = 1; i < MAX; i++) {
739 array[i] = array[i - 1];
741 array[i].tv_usec += event_rand() & 0xffff;
742 if (array[i].tv_usec > 1000000) {
743 array[i].tv_usec -= 1000000;
750 gettimeofday(&now, NULL);
753 int delay = (when.tv_sec - now.tv_sec) * 1000000;
754 delay += when.tv_usec;
755 delay -= now.tv_usec;
757 printf(
"\tsleep %d\n", delay);
bool fr_event_loop_exiting(fr_event_list_t *el)
fr_event_list_t * fr_event_list_create(TALLOC_CTX *ctx, fr_event_status_t status)
static fr_event_list_t * el
void(* fr_event_callback_t)(void *, struct timeval *now)
struct fr_event_fd_t fr_event_fd_t
int fr_event_now(fr_event_list_t *el, struct timeval *when)
void fr_randinit(fr_randctx *ctx, int flag)
int fr_event_delete(fr_event_list_t *el, fr_event_t **parent)
fr_event_callback_t callback
int fr_heap_extract(fr_heap_t *hp, void *data)
void fr_event_loop_exit(fr_event_list_t *el, int code)
int fr_event_loop(fr_event_list_t *el)
static fr_event_list_t * events
void * fr_heap_peek(fr_heap_t *hp)
void(* fr_event_status_t)(struct timeval *)
int fr_event_list_num_elements(fr_event_list_t *el)
fr_event_fd_handler_t handler
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
int fr_heap_insert(fr_heap_t *hp, void *data)
static int fr_event_list_time_cmp(void const *one, void const *two)
void fr_heap_delete(fr_heap_t *hp)
void fr_isaac(fr_randctx *ctx)
int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx, struct timeval *when, fr_event_t **parent)
int fr_event_fd_delete(fr_event_list_t *el, int type, int fd)
int fr_event_fd_insert(fr_event_list_t *el, int type, int fd, fr_event_fd_handler_t handler, void *ctx)
int fr_event_run(fr_event_list_t *el, struct timeval *when)
void fr_strerror_printf(char const *,...) CC_HINT(format(printf
fr_heap_t * fr_heap_create(fr_heap_cmp_t cmp, size_t offset)
int main(int argc, char *argv[])
fr_event_fd_t readers[FR_EV_MAX_FDS]
int fr_event_list_num_fds(fr_event_list_t *el)
void(* fr_event_fd_handler_t)(fr_event_list_t *el, int sock, void *ctx)
static int _event_list_free(fr_event_list_t *list)
size_t fr_heap_num_elements(fr_heap_t *hp)