summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stuge <peter@stuge.se>2010-02-16 03:35:41 +0100
committerPeter Stuge <peter@stuge.se>2010-02-16 06:58:32 +0100
commit091f0631d691145dc6bbffcc9c45922a0636d21c (patch)
treecc9dc201112455f516c84e445c450cd7e42306aa
parentcfce4d127184f4e4f334976151a0f80594bb5e22 (diff)
downloadlibusb-091f0631d691145dc6bbffcc9c45922a0636d21c.tar.gz
Add internal abstraction for POSIX Threadsusbi_sync
This prepares for a Windows backend without dependency on pthreads-w32. pthread_* is renamed to usbi_* and PTHREAD_* to USBI_*. A usbi_mutex_static_t and usbi_mutex_static_lock() and _unlock() are introduced for statically initialized mutexes, since they may be implemented using other types when pthreads mutexes aren't used. Move -pthread from libusb/Makefile.am to host-specific AM_CFLAGS in configure.ac. AM_CFLAGS is already used in Makefile.am.
-rw-r--r--configure.ac4
-rw-r--r--examples/Makefile.am1
-rw-r--r--libusb/Makefile.am6
-rw-r--r--libusb/core.c84
-rw-r--r--libusb/io.c111
-rw-r--r--libusb/libusbi.h28
-rw-r--r--libusb/os/darwin_usb.c8
-rw-r--r--libusb/os/linux_usbfs.c30
-rw-r--r--libusb/os/threads_posix.h44
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__ */