diff options
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | examples/Makefile.am | 1 | ||||
-rw-r--r-- | libusb/Makefile.am | 6 | ||||
-rw-r--r-- | libusb/core.c | 84 | ||||
-rw-r--r-- | libusb/io.c | 111 | ||||
-rw-r--r-- | libusb/libusbi.h | 28 | ||||
-rw-r--r-- | libusb/os/darwin_usb.c | 8 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.c | 30 | ||||
-rw-r--r-- | libusb/os/threads_posix.h | 44 |
9 files changed, 182 insertions, 134 deletions
diff --git a/configure.ac b/configure.ac index 093a875..be4cd3d 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,7 @@ case $host in AC_MSG_RESULT([Linux]) backend="linux" AC_CHECK_LIB(rt, clock_gettime) + AM_CFLAGS="-pthread" AM_LDFLAGS="" ;; *-darwin*) @@ -28,6 +29,7 @@ case $host in AC_DEFINE(USBI_OS_HANDLES_TIMEOUT, [], [Backend handles timeout]) AC_MSG_RESULT([Darwin/MacOS X]) backend="darwin" + AM_CFLAGS="-pthread" AM_LDFLAGS="-Wl,-framework -Wl,IOKit -Wl,-framework -Wl,CoreFoundation -Wl,-prebind -no-undefined" ;; *) @@ -120,7 +122,7 @@ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="") CFLAGS="$saved_cflags" -AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow" +AM_CFLAGS="$AM_CFLAGS -std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow" AC_SUBST(VISIBILITY_CFLAGS) AC_SUBST(AM_CFLAGS) diff --git a/examples/Makefile.am b/examples/Makefile.am index 600ebd4..1a91c3e 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -8,6 +8,5 @@ dpfp_SOURCES = dpfp.c dpfp_LDADD = ../libusb/libusb-1.0.la -lusb-1.0 dpfp_threaded_SOURCES = dpfp_threaded.c -dpfp_threaded_CFLAGS = -pthread $(AM_CFLAGS) dpfp_threaded_LDADD = ../libusb/libusb-1.0.la -lusb-1.0 diff --git a/libusb/Makefile.am b/libusb/Makefile.am index a2be46c..2f0d9e2 100644 --- a/libusb/Makefile.am +++ b/libusb/Makefile.am @@ -1,7 +1,7 @@ lib_LTLIBRARIES = libusb-1.0.la -LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c -DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c +LINUX_USBFS_SRC = os/threads_posix.h os/linux_usbfs.h os/linux_usbfs.c +DARWIN_USB_SRC = os/threads_posix.h os/darwin_usb.h os/darwin_usb.c EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) @@ -14,7 +14,7 @@ OS_SRC = $(DARWIN_USB_SRC) AM_CFLAGS_EXT = -no-cpp-precomp endif -libusb_1_0_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) -pthread +libusb_1_0_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC) hdrdir = $(includedir)/libusb-1.0 diff --git a/libusb/core.c b/libusb/core.c index 7e4fd24..698163a 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -41,7 +41,7 @@ const struct usbi_os_backend * const usbi_backend = &darwin_backend; #endif struct libusb_context *usbi_default_context = NULL; -static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; +usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER; /** * \mainpage libusb-1.0 API Reference @@ -506,7 +506,7 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, if (!dev) return NULL; - r = pthread_mutex_init(&dev->lock, NULL); + r = usbi_mutex_init(&dev->lock, NULL); if (r) return NULL; @@ -515,9 +515,9 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, dev->session_data = session_id; memset(&dev->os_priv, 0, priv_size); - pthread_mutex_lock(&ctx->usb_devs_lock); + usbi_mutex_lock(&ctx->usb_devs_lock); list_add(&dev->list, &ctx->usb_devs); - pthread_mutex_unlock(&ctx->usb_devs_lock); + usbi_mutex_unlock(&ctx->usb_devs_lock); return dev; } @@ -557,13 +557,13 @@ struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, struct libusb_device *dev; struct libusb_device *ret = NULL; - pthread_mutex_lock(&ctx->usb_devs_lock); + usbi_mutex_lock(&ctx->usb_devs_lock); list_for_each_entry(dev, &ctx->usb_devs, list) if (dev->session_data == session_id) { ret = dev; break; } - pthread_mutex_unlock(&ctx->usb_devs_lock); + usbi_mutex_unlock(&ctx->usb_devs_lock); return ret; } @@ -799,9 +799,9 @@ API_EXPORTED int libusb_get_max_iso_packet_size(libusb_device *dev, */ API_EXPORTED libusb_device *libusb_ref_device(libusb_device *dev) { - pthread_mutex_lock(&dev->lock); + usbi_mutex_lock(&dev->lock); dev->refcnt++; - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); return dev; } @@ -817,9 +817,9 @@ API_EXPORTED void libusb_unref_device(libusb_device *dev) if (!dev) return; - pthread_mutex_lock(&dev->lock); + usbi_mutex_lock(&dev->lock); refcnt = --dev->refcnt; - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); if (refcnt == 0) { usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address); @@ -827,9 +827,9 @@ API_EXPORTED void libusb_unref_device(libusb_device *dev) if (usbi_backend->destroy_device) usbi_backend->destroy_device(dev); - pthread_mutex_lock(&dev->ctx->usb_devs_lock); + usbi_mutex_lock(&dev->ctx->usb_devs_lock); list_del(&dev->list); - pthread_mutex_unlock(&dev->ctx->usb_devs_lock); + usbi_mutex_unlock(&dev->ctx->usb_devs_lock); free(dev); } @@ -867,7 +867,7 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) if (!_handle) return LIBUSB_ERROR_NO_MEM; - r = pthread_mutex_init(&_handle->lock, NULL); + r = usbi_mutex_init(&_handle->lock, NULL); if (r) return LIBUSB_ERROR_OTHER; @@ -882,9 +882,9 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) return r; } - pthread_mutex_lock(&ctx->open_devs_lock); + usbi_mutex_lock(&ctx->open_devs_lock); list_add(&_handle->list, &ctx->open_devs); - pthread_mutex_unlock(&ctx->open_devs_lock); + usbi_mutex_unlock(&ctx->open_devs_lock); *handle = _handle; @@ -896,17 +896,17 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) * so that it picks up the new fd, and then continues. */ /* record that we are messing with poll fds */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify++; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); /* write some data on control pipe to interrupt event handlers */ r = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); if (r <= 0) { usbi_warn(ctx, "internal signalling write failed"); - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); return 0; } @@ -919,9 +919,9 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) usbi_warn(ctx, "internal signalling read failed"); /* we're done with modifying poll fds */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); /* Release event handling lock and wake up event waiters */ libusb_unlock_events(ctx); @@ -983,9 +983,9 @@ out: static void do_close(struct libusb_context *ctx, struct libusb_device_handle *dev_handle) { - pthread_mutex_lock(&ctx->open_devs_lock); + usbi_mutex_lock(&ctx->open_devs_lock); list_del(&dev_handle->list); - pthread_mutex_unlock(&ctx->open_devs_lock); + usbi_mutex_unlock(&ctx->open_devs_lock); usbi_backend->close(dev_handle); libusb_unref_device(dev_handle->dev); @@ -1022,18 +1022,18 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle) * descriptor from the polling loop. */ /* record that we are messing with poll fds */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify++; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); /* write some data on control pipe to interrupt event handlers */ r = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); if (r <= 0) { usbi_warn(ctx, "internal signalling write failed, closing anyway"); do_close(ctx, dev_handle); - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); return; } @@ -1049,9 +1049,9 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle) do_close(ctx, dev_handle); /* we're done with modifying poll fds */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); /* Release event handling lock and wake up event waiters */ libusb_unlock_events(ctx); @@ -1198,7 +1198,7 @@ API_EXPORTED int libusb_claim_interface(libusb_device_handle *dev, if (interface_number >= sizeof(dev->claimed_interfaces) * 8) return LIBUSB_ERROR_INVALID_PARAM; - pthread_mutex_lock(&dev->lock); + usbi_mutex_lock(&dev->lock); if (dev->claimed_interfaces & (1 << interface_number)) goto out; @@ -1207,7 +1207,7 @@ API_EXPORTED int libusb_claim_interface(libusb_device_handle *dev, dev->claimed_interfaces |= 1 << interface_number; out: - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); return r; } @@ -1235,7 +1235,7 @@ API_EXPORTED int libusb_release_interface(libusb_device_handle *dev, if (interface_number >= sizeof(dev->claimed_interfaces) * 8) return LIBUSB_ERROR_INVALID_PARAM; - pthread_mutex_lock(&dev->lock); + usbi_mutex_lock(&dev->lock); if (!(dev->claimed_interfaces & (1 << interface_number))) { r = LIBUSB_ERROR_NOT_FOUND; goto out; @@ -1246,7 +1246,7 @@ API_EXPORTED int libusb_release_interface(libusb_device_handle *dev, dev->claimed_interfaces &= ~(1 << interface_number); out: - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); return r; } @@ -1279,12 +1279,12 @@ API_EXPORTED int libusb_set_interface_alt_setting(libusb_device_handle *dev, if (interface_number >= sizeof(dev->claimed_interfaces) * 8) return LIBUSB_ERROR_INVALID_PARAM; - pthread_mutex_lock(&dev->lock); + usbi_mutex_lock(&dev->lock); if (!(dev->claimed_interfaces & (1 << interface_number))) { - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); return LIBUSB_ERROR_NOT_FOUND; } - pthread_mutex_unlock(&dev->lock); + usbi_mutex_unlock(&dev->lock); return usbi_backend->set_interface_altsetting(dev, interface_number, alternate_setting); @@ -1476,8 +1476,8 @@ API_EXPORTED int libusb_init(libusb_context **context) goto err; } - pthread_mutex_init(&ctx->usb_devs_lock, NULL); - pthread_mutex_init(&ctx->open_devs_lock, NULL); + usbi_mutex_init(&ctx->usb_devs_lock, NULL); + usbi_mutex_init(&ctx->open_devs_lock, NULL); list_init(&ctx->usb_devs); list_init(&ctx->open_devs); @@ -1488,12 +1488,12 @@ API_EXPORTED int libusb_init(libusb_context **context) goto err; } - pthread_mutex_lock(&default_context_lock); + usbi_mutex_static_lock(&default_context_lock); if (!usbi_default_context) { usbi_dbg("created default context"); usbi_default_context = ctx; } - pthread_mutex_unlock(&default_context_lock); + usbi_mutex_static_unlock(&default_context_lock); if (context) *context = ctx; @@ -1523,12 +1523,12 @@ API_EXPORTED void libusb_exit(struct libusb_context *ctx) if (usbi_backend->exit) usbi_backend->exit(); - pthread_mutex_lock(&default_context_lock); + usbi_mutex_static_lock(&default_context_lock); if (ctx == usbi_default_context) { usbi_dbg("freeing default context"); usbi_default_context = NULL; } - pthread_mutex_unlock(&default_context_lock); + usbi_mutex_static_unlock(&default_context_lock); free(ctx); } diff --git a/libusb/io.c b/libusb/io.c index 387be4c..82cd52d 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -21,7 +21,6 @@ #include <config.h> #include <errno.h> #include <poll.h> -#include <pthread.h> #include <signal.h> #include <stdint.h> #include <stdlib.h> @@ -998,12 +997,12 @@ int usbi_io_init(struct libusb_context *ctx) { int r; - pthread_mutex_init(&ctx->flying_transfers_lock, NULL); - pthread_mutex_init(&ctx->pollfds_lock, NULL); - pthread_mutex_init(&ctx->pollfd_modify_lock, NULL); - pthread_mutex_init(&ctx->events_lock, NULL); - pthread_mutex_init(&ctx->event_waiters_lock, NULL); - pthread_cond_init(&ctx->event_waiters_cond, NULL); + usbi_mutex_init(&ctx->flying_transfers_lock, NULL); + usbi_mutex_init(&ctx->pollfds_lock, NULL); + usbi_mutex_init(&ctx->pollfd_modify_lock, NULL); + usbi_mutex_init(&ctx->events_lock, NULL); + usbi_mutex_init(&ctx->event_waiters_lock, NULL); + usbi_cond_init(&ctx->event_waiters_cond, NULL); list_init(&ctx->flying_transfers); list_init(&ctx->pollfds); @@ -1088,7 +1087,7 @@ static int add_to_flying_list(struct usbi_transfer *transfer) int r = 0; int first = 1; - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); /* if we have no other flying transfers, start the list with this one */ if (list_empty(&ctx->flying_transfers)) { @@ -1122,7 +1121,7 @@ static int add_to_flying_list(struct usbi_transfer *transfer) /* otherwise we need to be inserted at the end */ list_add_tail(&transfer->list, &ctx->flying_transfers); out: - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); return r; } @@ -1163,7 +1162,7 @@ API_EXPORTED struct libusb_transfer *libusb_alloc_transfer(int iso_packets) memset(itransfer, 0, alloc_size); itransfer->num_iso_packets = iso_packets; - pthread_mutex_init(&itransfer->lock, NULL); + usbi_mutex_init(&itransfer->lock, NULL); return __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); } @@ -1194,7 +1193,7 @@ API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer) free(transfer->buffer); itransfer = __LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); - pthread_mutex_destroy(&itransfer->lock); + usbi_mutex_destroy(&itransfer->lock); free(itransfer); } @@ -1216,7 +1215,7 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer) int r; int first; - pthread_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->lock); itransfer->transferred = 0; itransfer->flags = 0; r = calculate_timeout(itransfer); @@ -1228,9 +1227,9 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer) first = add_to_flying_list(itransfer); r = usbi_backend->submit_transfer(itransfer); if (r) { - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); list_del(&itransfer->list); - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); } #ifdef USBI_TIMERFD_AVAILABLE else if (first && usbi_using_timerfd(ctx)) { @@ -1246,7 +1245,7 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer) #endif out: - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return r; } @@ -1271,12 +1270,12 @@ API_EXPORTED int libusb_cancel_transfer(struct libusb_transfer *transfer) int r; usbi_dbg(""); - pthread_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->lock); r = usbi_backend->cancel_transfer(itransfer); if (r < 0) usbi_err(TRANSFER_CTX(transfer), "cancel transfer failed error %d", r); - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return r; } @@ -1360,10 +1359,10 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, * to rearm the timerfd if the transfer that expired was the one with * the shortest timeout. */ - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); list_del(&itransfer->list); r = arm_timerfd_for_next_timeout(ctx); - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); if (r < 0) { return r; @@ -1393,9 +1392,9 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, * this point. */ if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) libusb_free_transfer(transfer); - pthread_mutex_lock(&ctx->event_waiters_lock); - pthread_cond_broadcast(&ctx->event_waiters_cond); - pthread_mutex_unlock(&ctx->event_waiters_lock); + usbi_mutex_lock(&ctx->event_waiters_lock); + usbi_cond_broadcast(&ctx->event_waiters_cond); + usbi_mutex_unlock(&ctx->event_waiters_lock); return 0; } @@ -1443,15 +1442,15 @@ API_EXPORTED int libusb_try_lock_events(libusb_context *ctx) /* is someone else waiting to modify poll fds? if so, don't let this thread * start event handling */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); r = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); if (r) { usbi_dbg("someone else is modifying poll fds"); return 1; } - r = pthread_mutex_trylock(&ctx->events_lock); + r = usbi_mutex_trylock(&ctx->events_lock); if (r) return 1; @@ -1480,7 +1479,7 @@ API_EXPORTED int libusb_try_lock_events(libusb_context *ctx) API_EXPORTED void libusb_lock_events(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->events_lock); + usbi_mutex_lock(&ctx->events_lock); ctx->event_handler_active = 1; } @@ -1496,14 +1495,14 @@ API_EXPORTED void libusb_unlock_events(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); ctx->event_handler_active = 0; - pthread_mutex_unlock(&ctx->events_lock); + usbi_mutex_unlock(&ctx->events_lock); /* FIXME: perhaps we should be a bit more efficient by not broadcasting * the availability of the events lock when we are modifying pollfds * (check ctx->pollfd_modify)? */ - pthread_mutex_lock(&ctx->event_waiters_lock); - pthread_cond_broadcast(&ctx->event_waiters_cond); - pthread_mutex_unlock(&ctx->event_waiters_lock); + usbi_mutex_lock(&ctx->event_waiters_lock); + usbi_cond_broadcast(&ctx->event_waiters_cond); + usbi_mutex_unlock(&ctx->event_waiters_lock); } /** \ingroup poll @@ -1534,9 +1533,9 @@ API_EXPORTED int libusb_event_handling_ok(libusb_context *ctx) /* is someone else waiting to modify poll fds? if so, don't let this thread * continue event handling */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); r = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); if (r) { usbi_dbg("someone else is modifying poll fds"); return 0; @@ -1562,9 +1561,9 @@ API_EXPORTED int libusb_event_handler_active(libusb_context *ctx) /* is someone else waiting to modify poll fds? if so, don't let this thread * start event handling -- indicate that event handling is happening */ - pthread_mutex_lock(&ctx->pollfd_modify_lock); + usbi_mutex_lock(&ctx->pollfd_modify_lock); r = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); + usbi_mutex_unlock(&ctx->pollfd_modify_lock); if (r) { usbi_dbg("someone else is modifying poll fds"); return 1; @@ -1595,7 +1594,7 @@ API_EXPORTED int libusb_event_handler_active(libusb_context *ctx) API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->event_waiters_lock); + usbi_mutex_lock(&ctx->event_waiters_lock); } /** \ingroup poll @@ -1606,7 +1605,7 @@ API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx) API_EXPORTED void libusb_unlock_event_waiters(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); - pthread_mutex_unlock(&ctx->event_waiters_lock); + usbi_mutex_unlock(&ctx->event_waiters_lock); } /** \ingroup poll @@ -1641,7 +1640,7 @@ API_EXPORTED int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) USBI_GET_CONTEXT(ctx); if (tv == NULL) { - pthread_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock); + usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock); return 0; } @@ -1658,7 +1657,7 @@ API_EXPORTED int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) timeout.tv_sec++; } - r = pthread_cond_timedwait(&ctx->event_waiters_cond, + r = usbi_cond_timedwait(&ctx->event_waiters_cond, &ctx->event_waiters_lock, &timeout); return (r == ETIMEDOUT); } @@ -1732,9 +1731,9 @@ static int handle_timeouts(struct libusb_context *ctx) { int r; USBI_GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); r = handle_timeouts_locked(ctx); - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); return r; } #endif @@ -1748,7 +1747,7 @@ static int handle_timerfd_trigger(struct libusb_context *ctx) if (r < 0) return r; - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); /* process the timeout that just happened */ r = handle_timeouts_locked(ctx); @@ -1759,7 +1758,7 @@ static int handle_timerfd_trigger(struct libusb_context *ctx) r = arm_timerfd_for_next_timeout(ctx); out: - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); return r; } #endif @@ -1775,7 +1774,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) int i = -1; int timeout_ms; - pthread_mutex_lock(&ctx->pollfds_lock); + usbi_mutex_lock(&ctx->pollfds_lock); list_for_each_entry(ipollfd, &ctx->pollfds, list) nfds++; @@ -1792,7 +1791,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) fds[i].events = pollfd->events; fds[i].revents = 0; } - pthread_mutex_unlock(&ctx->pollfds_lock); + usbi_mutex_unlock(&ctx->pollfds_lock); timeout_ms = (tv->tv_sec * 1000) + (tv->tv_usec / 1000); @@ -2090,9 +2089,9 @@ API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx, if (usbi_using_timerfd(ctx)) return 0; - pthread_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&ctx->flying_transfers_lock); if (list_empty(&ctx->flying_transfers)) { - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); usbi_dbg("no URBs, no timeout!"); return 0; } @@ -2104,7 +2103,7 @@ API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx, break; } } - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&ctx->flying_transfers_lock); if (!found) { usbi_dbg("all URBs have already been processed for timeouts"); @@ -2183,9 +2182,9 @@ int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events) usbi_dbg("add fd %d events %d", fd, events); ipollfd->pollfd.fd = fd; ipollfd->pollfd.events = events; - pthread_mutex_lock(&ctx->pollfds_lock); + usbi_mutex_lock(&ctx->pollfds_lock); list_add_tail(&ipollfd->list, &ctx->pollfds); - pthread_mutex_unlock(&ctx->pollfds_lock); + usbi_mutex_unlock(&ctx->pollfds_lock); if (ctx->fd_added_cb) ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); @@ -2199,7 +2198,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd) int found = 0; usbi_dbg("remove fd %d", fd); - pthread_mutex_lock(&ctx->pollfds_lock); + usbi_mutex_lock(&ctx->pollfds_lock); list_for_each_entry(ipollfd, &ctx->pollfds, list) if (ipollfd->pollfd.fd == fd) { found = 1; @@ -2208,12 +2207,12 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd) if (!found) { usbi_dbg("couldn't find fd %d to remove", fd); - pthread_mutex_unlock(&ctx->pollfds_lock); + usbi_mutex_unlock(&ctx->pollfds_lock); return; } list_del(&ipollfd->list); - pthread_mutex_unlock(&ctx->pollfds_lock); + usbi_mutex_unlock(&ctx->pollfds_lock); free(ipollfd); if (ctx->fd_removed_cb) ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); @@ -2239,7 +2238,7 @@ API_EXPORTED const struct libusb_pollfd **libusb_get_pollfds( size_t cnt = 0; USBI_GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->pollfds_lock); + usbi_mutex_lock(&ctx->pollfds_lock); list_for_each_entry(ipollfd, &ctx->pollfds, list) cnt++; @@ -2252,7 +2251,7 @@ API_EXPORTED const struct libusb_pollfd **libusb_get_pollfds( ret[cnt] = NULL; out: - pthread_mutex_unlock(&ctx->pollfds_lock); + usbi_mutex_unlock(&ctx->pollfds_lock); return (const struct libusb_pollfd **) ret; } @@ -2281,14 +2280,14 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle) */ while (1) { - pthread_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock); + usbi_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock); to_cancel = NULL; list_for_each_entry(cur, &HANDLE_CTX(handle)->flying_transfers, list) if (__USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == handle) { to_cancel = cur; break; } - pthread_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock); + usbi_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock); if (!to_cancel) break; diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 10a4994..740e249 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -24,7 +24,6 @@ #include <config.h> #include <poll.h> -#include <pthread.h> #include <stddef.h> #include <time.h> @@ -138,6 +137,11 @@ void usbi_log(struct libusb_context *ctx, enum usbi_log_level, #define ITRANSFER_CTX(transfer) \ (TRANSFER_CTX(__USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer))) +/* Internal abstraction for thread synchronization */ +#if defined(OS_LINUX) || defined(OS_DARWIN) +#include <os/threads_posix.h> +#endif + extern struct libusb_context *usbi_default_context; struct libusb_context { @@ -149,28 +153,28 @@ struct libusb_context { int ctrl_pipe[2]; struct list_head usb_devs; - pthread_mutex_t usb_devs_lock; + usbi_mutex_t usb_devs_lock; /* A list of open handles. Backends are free to traverse this if required. */ struct list_head open_devs; - pthread_mutex_t open_devs_lock; + usbi_mutex_t open_devs_lock; /* this is a list of in-flight transfer handles, sorted by timeout * expiration. URBs to timeout the soonest are placed at the beginning of * the list, URBs that will time out later are placed after, and urbs with * infinite timeout are always placed at the very end. */ struct list_head flying_transfers; - pthread_mutex_t flying_transfers_lock; + usbi_mutex_t flying_transfers_lock; /* list of poll fds */ struct list_head pollfds; - pthread_mutex_t pollfds_lock; + usbi_mutex_t pollfds_lock; /* a counter that is set when we want to interrupt event handling, in order * to modify the poll fd set. and a lock to protect it. */ unsigned int pollfd_modify; - pthread_mutex_t pollfd_modify_lock; + usbi_mutex_t pollfd_modify_lock; /* user callbacks for pollfd changes */ libusb_pollfd_added_cb fd_added_cb; @@ -178,15 +182,15 @@ struct libusb_context { void *fd_cb_user_data; /* ensures that only one thread is handling events at any one time */ - pthread_mutex_t events_lock; + usbi_mutex_t events_lock; /* used to see if there is an active thread doing event handling */ int event_handler_active; /* used to wait for event completion in threads other than the one that is * event handling */ - pthread_mutex_t event_waiters_lock; - pthread_cond_t event_waiters_cond; + usbi_mutex_t event_waiters_lock; + usbi_cond_t event_waiters_cond; #ifdef USBI_TIMERFD_AVAILABLE /* used for timeout handling, if supported by OS. @@ -204,7 +208,7 @@ struct libusb_context { struct libusb_device { /* lock protects refcnt, everything else is finalized at initialization * time */ - pthread_mutex_t lock; + usbi_mutex_t lock; int refcnt; struct libusb_context *ctx; @@ -220,7 +224,7 @@ struct libusb_device { struct libusb_device_handle { /* lock protects claimed_interfaces */ - pthread_mutex_t lock; + usbi_mutex_t lock; unsigned long claimed_interfaces; struct list_head list; @@ -262,7 +266,7 @@ struct usbi_transfer { * cancelling the transfer from another thread while you are processing * its completion (presumably there would be races within your OS backend * if this were possible). */ - pthread_mutex_t lock; + usbi_mutex_t lock; }; #define __USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index fb5b8d5..6310f5a 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -231,7 +231,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { CFRelease (locationCF); IOObjectRelease (device); - pthread_mutex_lock(&ctx->open_devs_lock); + usbi_mutex_lock(&ctx->open_devs_lock); list_for_each_entry(handle, &ctx->open_devs, list) { dpriv = (struct darwin_device_priv *)handle->dev->os_priv; @@ -244,7 +244,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { } } - pthread_mutex_unlock(&ctx->open_devs_lock); + usbi_mutex_unlock(&ctx->open_devs_lock); } } @@ -1450,7 +1450,7 @@ static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds int i = 0, ret; UInt32 message; - pthread_mutex_lock(&ctx->open_devs_lock); + usbi_mutex_lock(&ctx->open_devs_lock); for (i = 0; i < nfds && num_ready > 0; i++) { struct pollfd *pollfd = &fds[i]; struct libusb_device_handle *handle; @@ -1503,7 +1503,7 @@ static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds } } - pthread_mutex_unlock(&ctx->open_devs_lock); + usbi_mutex_unlock(&ctx->open_devs_lock); return 0; } diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index ffa4088..b1b98ca 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -1775,7 +1775,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, enum libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; int r = 0; - pthread_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->lock); usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status, urb_idx + 1, num_urbs); @@ -1819,7 +1819,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, if (tpriv->reap_action == CANCELLED) { free(tpriv->urbs); tpriv->urbs = NULL; - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); r = usbi_handle_transfer_cancellation(itransfer); goto out_unlock; } @@ -1897,10 +1897,10 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, completed: free(tpriv->urbs); tpriv->urbs = NULL; - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, status); out_unlock: - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return r; } @@ -1914,7 +1914,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, int urb_idx = 0; int i; - pthread_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->lock); for (i = 0; i < num_urbs; i++) { if (urb == tpriv->iso_urbs[i]) { urb_idx = i + 1; @@ -1923,7 +1923,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, } if (urb_idx == 0) { usbi_err(TRANSFER_CTX(transfer), "could not locate urb!"); - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return LIBUSB_ERROR_NOT_FOUND; } @@ -1951,10 +1951,10 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, usbi_dbg("CANCEL: last URB handled, reporting"); free_iso_urbs(tpriv); if (tpriv->reap_action == CANCELLED) { - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_cancellation(itransfer); } else { - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_ERROR); } @@ -1981,12 +1981,12 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, if (urb_idx == num_urbs) { usbi_dbg("last URB in transfer --> complete!"); free_iso_urbs(tpriv); - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); } out: - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return 0; } @@ -1996,7 +1996,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer, struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); int status; - pthread_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->lock); usbi_dbg("handling completion status %d", urb->status); if (urb->status == 0) @@ -2008,7 +2008,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer, "cancel: unrecognised urb status %d", urb->status); free(tpriv->urbs); tpriv->urbs = NULL; - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_cancellation(itransfer); } @@ -2036,7 +2036,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer, free(tpriv->urbs); tpriv->urbs = NULL; - pthread_mutex_unlock(&itransfer->lock); + usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, status); } @@ -2087,7 +2087,7 @@ static int op_handle_events(struct libusb_context *ctx, int r; int i = 0; - pthread_mutex_lock(&ctx->open_devs_lock); + usbi_mutex_lock(&ctx->open_devs_lock); for (i = 0; i < nfds && num_ready > 0; i++) { struct pollfd *pollfd = &fds[i]; struct libusb_device_handle *handle; @@ -2118,7 +2118,7 @@ static int op_handle_events(struct libusb_context *ctx, r = 0; out: - pthread_mutex_unlock(&ctx->open_devs_lock); + usbi_mutex_unlock(&ctx->open_devs_lock); return r; } diff --git a/libusb/os/threads_posix.h b/libusb/os/threads_posix.h new file mode 100644 index 0000000..b801847 --- /dev/null +++ b/libusb/os/threads_posix.h @@ -0,0 +1,44 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright (C) 2010 Peter Stuge <peter@stuge.se> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __LIBUSB_THREADS_POSIX_H__ +#define __LIBUSB_THREADS_POSIX_H__ + +#include <pthread.h> + +#define usbi_mutex_static_t static pthread_mutex_t +#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define usbi_mutex_static_lock pthread_mutex_lock +#define usbi_mutex_static_unlock pthread_mutex_unlock + +#define usbi_mutex_t pthread_mutex_t +#define usbi_mutex_init pthread_mutex_init +#define usbi_mutex_lock pthread_mutex_lock +#define usbi_mutex_unlock pthread_mutex_unlock +#define usbi_mutex_trylock pthread_mutex_trylock +#define usbi_mutex_destroy pthread_mutex_destroy + +#define usbi_cond_t pthread_cond_t +#define usbi_cond_init pthread_cond_init +#define usbi_cond_wait pthread_cond_wait +#define usbi_cond_timedwait pthread_cond_timedwait +#define usbi_cond_broadcast pthread_cond_broadcast + +#endif /* __LIBUSB_THREADS_POSIX_H__ */ |