From b5f43b29e77f4bc867146acf1f6f18c3f4ad71b5 Mon Sep 17 00:00:00 2001 From: Chris Dickens Date: Mon, 25 Aug 2014 23:26:53 -0700 Subject: core: Be more efficient by not passing internal fds to backend There are a number of fds that the core uses internally. Currently any events on these fds are masked out so that the backend will skip over them during handle_events(). This change improves upon this by simply not providing these fds to the backend. Signed-off-by: Chris Dickens --- libusb/io.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/libusb/io.c b/libusb/io.c index 8377a5e..430f67e 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1961,11 +1961,27 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) int r; struct usbi_pollfd *ipollfd; POLL_NFDS_TYPE nfds = 0; + POLL_NFDS_TYPE internal_nfds; struct pollfd *fds = NULL; int i = -1; int timeout_ms; int special_event; + /* there are certain fds that libusb uses internally, currently: + * + * 1) control pipe + * 2) hotplug pipe + * 3) timerfd + * + * the backend will never need to attempt to handle events on these fds, so + * we determine how many fds are in use internally for this context and when + * handle_events() is called in the backend, the pollfd list and count will + * be adjusted to skip over these internal fds */ + if (usbi_using_timerfd(ctx)) + internal_nfds = 3; + else + internal_nfds = 2; + usbi_mutex_lock(&ctx->pollfds_lock); list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd) nfds++; @@ -2019,14 +2035,8 @@ redo_poll: * simply return */ usbi_dbg("caught a fish on the control pipe"); - if (r == 1) { - r = 0; + if (0 == --r) goto handled; - } else { - /* prevent OS backend from trying to handle events on ctrl pipe */ - fds[0].revents = 0; - r--; - } } /* fd[1] is always the hotplug pipe */ @@ -2052,8 +2062,7 @@ redo_poll: if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message.event) libusb_unref_device(message.device); - fds[1].revents = 0; - if (1 == r--) + if (0 == --r) goto handled; } /* else there shouldn't be anything on this pipe */ @@ -2070,28 +2079,22 @@ redo_poll: /* return error code */ r = ret; goto handled; - } else if (r == 1) { - /* no more active file descriptors, nothing more to do */ - r = 0; - goto handled; - } else { - /* more events pending... - * prevent OS backend from trying to handle events on timerfd */ - fds[2].revents = 0; - r--; } + + if (0 == --r) + goto handled; } #endif - r = usbi_backend->handle_events(ctx, fds, nfds, r); + r = usbi_backend->handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r); if (r) usbi_err(ctx, "backend handle_events failed with error %d", r); handled: - if (r == 0 && special_event) { - timeout_ms = 0; - goto redo_poll; - } + if (r == 0 && special_event) { + timeout_ms = 0; + goto redo_poll; + } free(fds); return r; -- cgit v1.2.3