Previously it was necessary to count the number of pollfds contained in a linked list. This change introduces the optimisation of storing a running total of the number of pollfds. --- libusb/io.c | 16 ++++++++-------- libusb/libusbi.h | 1 + 2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/libusb/io.c b/libusb/io.c index 314184f..d6eb3b5 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1060,6 +1060,7 @@ int usbi_io_init(struct libusb_context *ctx) usbi_cond_init(&ctx->event_waiters_cond, NULL); list_init(&ctx->flying_transfers); list_init(&ctx->pollfds); + ctx->pollfds_cnt = 0; /* FIXME should use an eventfd on kernels that support it */ r = usbi_pipe(ctx->ctrl_pipe); @@ -1893,8 +1894,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) int timeout_ms; usbi_mutex_lock(&ctx->pollfds_lock); - list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd) - nfds++; + nfds = ctx->pollfds_cnt; /* TODO: malloc when number of fd's changes, not on every poll */ if (nfds != 0) @@ -2421,6 +2421,7 @@ int usbi_add_pollfd(struct libusb_context *ctx, libusb_event_handle handle, shor ipollfd->pollfd.direction = poll_events_to_event_dirs(events); usbi_mutex_lock(&ctx->pollfds_lock); list_add_tail(&ipollfd->list, &ctx->pollfds); + ++ctx->pollfds_cnt; usbi_mutex_unlock(&ctx->pollfds_lock); #ifdef LIBUSB_EVENT_HANDLE_IS_FD @@ -2453,6 +2454,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, libusb_event_handle handle) } list_del(&ipollfd->list); + --ctx->pollfds_cnt; usbi_mutex_unlock(&ctx->pollfds_lock); free(ipollfd); #ifdef LIBUSB_EVENT_HANDLE_IS_FD @@ -2492,9 +2494,8 @@ const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->pollfds_lock); - list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd) - cnt++; - + cnt = ctx->pollfds_cnt; + /* Allocate enough space for the pointers and the libusb_event * structures after the last pointer. */ alloc_size = ((cnt + 1) * sizeof(struct libusb_pollfd *)) + @@ -2553,9 +2554,8 @@ struct libusb_event ** LIBUSB_CALL libusb_get_events( USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->pollfds_lock); - list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd) - cnt++; - + cnt = ctx->pollfds_cnt; + /* Allocate enough space for the pointers and the libusb_event * structures after the last pointer. */ alloc_size = ((cnt + 1) * sizeof(struct libusb_event *)) + diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 7c4f1f1..52d39ff 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -247,6 +247,7 @@ struct libusb_context { /* list of poll fds */ struct list_head pollfds; + size_t pollfds_cnt; usbi_mutex_t pollfds_lock; /* a counter that is set when we want to interrupt event handling, in order -- 1.7.9.5 ------------------------------------------------------------------------------ This SF.net email is sponsored by Windows: Build for Windows Store. http://p.sf.net/sfu/windows-dev2dev _______________________________________________ libusbx-devel mailing list libusbx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libusbx-devel