From: Arran Cudbard-Bell Date: Wed, 5 Jul 2017 01:48:32 +0000 (-0400) Subject: EVFILT_READ and EVFILT_WRITE need to be added as separate events X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7529a35291a6bb8097fd7e29b9f2d429663c1fe2;p=thirdparty%2Ffreeradius-server.git EVFILT_READ and EVFILT_WRITE need to be added as separate events --- diff --git a/src/lib/io/network.c b/src/lib/io/network.c index 46094a8be41..f5f4375c830 100644 --- a/src/lib/io/network.c +++ b/src/lib/io/network.c @@ -393,7 +393,7 @@ static void fr_network_read(UNUSED fr_event_list_t *el, int sockfd, UNUSED int f } } - +#if 0 /** Write packets to the network. * * @param el the event list @@ -410,6 +410,7 @@ static void fr_network_write(UNUSED fr_event_list_t *el, UNUSED int sockfd, UNUS talloc_free(s); } } +#endif /** Handle errors for a socket. * @@ -490,7 +491,7 @@ static void fr_network_socket_callback(void *ctx, void const *data, size_t data_ if (fr_event_fd_insert(nr->el, fd, fr_network_read, - app_io->write ? fr_network_write : NULL, + NULL, /* app_io->write ? fr_network_write : NULL - FIXME */ app_io->error ? fr_network_error : NULL, s) < 0) { fr_log(nr->log, L_ERR, "Failed adding new socket to event loop: %s", fr_strerror()); diff --git a/src/lib/util/event.c b/src/lib/util/event.c index 87e79db5adf..583a6d0b761 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -289,17 +289,17 @@ int fr_event_fd_delete(fr_event_list_t *el, int fd) */ static int _fr_event_fd_free(fr_event_fd_t *ef) { - int16_t filter = 0; - struct kevent evset; + struct kevent evset[2]; fr_event_list_t *el = talloc_parent(ef); - if (ef->read) filter |= EVFILT_READ; - if (ef->write) filter |= EVFILT_WRITE; - if (ef->is_registered) { - EV_SET(&evset, ef->fd, filter, EV_DELETE, 0, 0, 0); - if (kevent(el->kq, &evset, 1, NULL, 0, NULL) < 0) { + int count = 0; + + if (ef->read) EV_SET(&evset[count++], ef->fd, EVFILT_READ, EV_DELETE, 0, 0, 0); + if (ef->write) EV_SET(&evset[count++], ef->fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + + if (kevent(el->kq, evset, count, NULL, 0, NULL) < 0) { fr_strerror_printf("Failed removing filters for FD %i: %s", ef->fd, fr_syserror(errno)); return -1; } @@ -331,7 +331,8 @@ int fr_event_fd_insert(fr_event_list_t *el, int fd, void *ctx) { int16_t filter = 0; - struct kevent evset; + int count = 0; + struct kevent evset[2]; fr_event_fd_t *ef, find; bool pre_existing; @@ -412,19 +413,17 @@ int fr_event_fd_insert(fr_event_list_t *el, int fd, } else { pre_existing = true; - if (ef->read && !read_fn) filter |= EVFILT_READ; - if (ef->write && !write_fn) filter |= EVFILT_WRITE; - - if (filter) { - EV_SET(&evset, ef->fd, filter, EV_DELETE, 0, 0, 0); + if (ef->read && !read_fn) EV_SET(&evset[count++], ef->fd, EVFILT_READ, EV_DELETE, 0, 0, 0); + if (ef->write && !write_fn) EV_SET(&evset[count++], ef->fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + if (count) { /* * kevent on macOS sierra (and possibly others) * is broken, and doesn't allow us to perform * an EVILT_* add and delete in the same * call. */ - if (kevent(el->kq, &evset, 1, NULL, 0, NULL) < 0) { + if (kevent(el->kq, evset, count, NULL, 0, NULL) < 0) { fr_strerror_printf("Failed deleting filter for FD %i: %s", fd, fr_syserror(errno)); return -1; } @@ -437,17 +436,18 @@ int fr_event_fd_insert(fr_event_list_t *el, int fd, * events we unset the deferred_delete flag. */ ef->deferred_delete = false; + count = 0; } ef->ctx = ctx; ef->read = read_fn; - if (read_fn) filter |= EVFILT_READ; ef->write = write_fn; - if (write_fn) filter |= EVFILT_WRITE; ef->error = error; - EV_SET(&evset, fd, filter, EV_ADD | EV_ENABLE, 0, 0, ef); - if (kevent(el->kq, &evset, 1, NULL, 0, NULL) < 0) { + if (read_fn) EV_SET(&evset[count++], fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, ef); + if (write_fn) EV_SET(&evset[count++], fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, ef); + + if (kevent(el->kq, evset, count, NULL, 0, NULL) < 0) { fr_strerror_printf("Failed adding filter for FD %i: %s", fd, fr_syserror(errno)); if (!pre_existing) talloc_free(ef); return -1;