Add internal abstraction for POSIX Threads
authorPeter Stuge <peter@stuge.se>
Mon, 10 May 2010 23:51:43 +0000 (00:51 +0100)
committerDaniel Drake <dan@reactivated.net>
Thu, 13 May 2010 01:11:29 +0000 (22:11 -0300)
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 THREAD_CFLAGS in
configure.ac. This will enable optional use of -lpthread for cygwin.

[dsd: minor tweaks, and roll in a change based on patches from Pete
Batard to only build dpfp_threaded example when we're using pthreads]

AUTHORS
configure.ac
examples/Makefile.am
libusb/Makefile.am
libusb/core.c
libusb/io.c
libusb/libusbi.h
libusb/os/darwin_usb.c
libusb/os/linux_usbfs.c
libusb/os/threads_posix.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index dc0e053..f855002 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,6 +14,7 @@ Hans Ulrich Niedermann
 Ludovic Rousseau
 Martin Koegler
 Mikhail Gusarov
+Peter Stuge
 Rob Walker
 Toby Peterson
 Vasily Khoruzhick
index 4668cf0..ba9814f 100644 (file)
@@ -20,6 +20,8 @@ case $host in
        AC_MSG_RESULT([Linux])
        backend="linux"
        AC_CHECK_LIB(rt, clock_gettime)
+       threads="posix"
+       THREAD_CFLAGS="-pthread"
        AM_LDFLAGS=""
        ;;
 *-darwin*)
@@ -28,6 +30,8 @@ case $host in
        AC_DEFINE(USBI_OS_HANDLES_TIMEOUT, [], [Backend handles timeout])
        AC_MSG_RESULT([Darwin/MacOS X])
        backend="darwin"
+       threads="posix"
+       THREAD_CFLAGS="-pthread"
        AM_LDFLAGS="-Wl,-framework -Wl,IOKit -Wl,-framework -Wl,CoreFoundation -Wl,-prebind -no-undefined"
        ;;
 *)
@@ -36,6 +40,7 @@ esac
 
 AM_CONDITIONAL([OS_LINUX], [test "x$backend" == "xlinux"])
 AM_CONDITIONAL([OS_DARWIN], [test "x$backend" == "xdarwin"])
+AM_CONDITIONAL([THREADS_POSIX], [test "x$threads" == "xposix"])
 
 # Library versioning
 lt_major="0"
@@ -120,6 +125,8 @@ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
        nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="")
 CFLAGS="$saved_cflags"
 
+AC_SUBST([THREAD_CFLAGS])
+
 AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
 
 AC_SUBST(VISIBILITY_CFLAGS)
index 600ebd4..bed1837 100644 (file)
@@ -1,5 +1,5 @@
 INCLUDES = -I$(top_srcdir)
-noinst_PROGRAMS = lsusb dpfp dpfp_threaded
+noinst_PROGRAMS = lsusb dpfp
 
 lsusb_SOURCES = lsusb.c
 lsusb_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
@@ -7,7 +7,10 @@ lsusb_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
 dpfp_SOURCES = dpfp.c
 dpfp_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
 
+if THREADS_POSIX
 dpfp_threaded_SOURCES = dpfp_threaded.c
-dpfp_threaded_CFLAGS = -pthread $(AM_CFLAGS)
+dpfp_threaded_CFLAGS = $(THREAD_CFLAGS) $(AM_CFLAGS)
 dpfp_threaded_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
+noinst_PROGRAMS += dpfp_threaded
+endif
 
index a2be46c..8784db4 100644 (file)
@@ -14,8 +14,8 @@ 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_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC)
+libusb_1_0_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) $(THREAD_CFLAGS)
+libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c os/threads_posix.h $(OS_SRC)
 
 hdrdir = $(includedir)/libusb-1.0
 hdr_HEADERS = libusb.h
index 7e4fd24..0f5b894 100644 (file)
@@ -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;
+static 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);
 }
index 1379eb3..ce661ad 100644 (file)
@@ -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>
@@ -1005,12 +1004,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);
 
@@ -1095,7 +1094,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)) {
@@ -1129,7 +1128,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;
 }
 
@@ -1170,7 +1169,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);
 }
 
@@ -1201,7 +1200,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);
 }
 
@@ -1223,7 +1222,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);
@@ -1235,9 +1234,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)) {
@@ -1253,7 +1252,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;
 }
 
@@ -1278,12 +1277,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;
 }
 
@@ -1367,10 +1366,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;
@@ -1400,9 +1399,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;
 }
 
@@ -1450,15 +1449,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;
 
@@ -1487,7 +1486,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;
 }
 
@@ -1503,14 +1502,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
@@ -1541,9 +1540,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;
@@ -1569,9 +1568,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;
@@ -1602,7 +1601,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
@@ -1613,7 +1612,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
@@ -1648,7 +1647,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;
        }
 
@@ -1665,7 +1664,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);
 }
@@ -1739,9 +1738,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
@@ -1755,7 +1754,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);
@@ -1766,7 +1765,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
@@ -1782,7 +1781,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++;
 
@@ -1799,7 +1798,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);
 
@@ -2097,9 +2096,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;
        }
@@ -2111,7 +2110,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");
@@ -2190,9 +2189,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);
@@ -2206,7 +2205,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;
@@ -2215,12 +2214,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);
@@ -2246,7 +2245,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++;
 
@@ -2259,7 +2258,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;
 }
 
@@ -2288,14 +2287,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;
index 10a4994..740e249 100644 (file)
@@ -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) \
index 0e69e77..517b77d 100644 (file)
@@ -232,7 +232,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;
 
@@ -245,7 +245,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);
   }
 }
 
@@ -1388,7 +1388,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;
@@ -1441,7 +1441,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;
 }
index 65f29ae..f89a87d 100644 (file)
@@ -1792,7 +1792,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);
 
@@ -1836,7 +1836,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;
                        }
@@ -1914,10 +1914,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;
 }
 
@@ -1931,7 +1931,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;
@@ -1940,7 +1940,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;
        }
 
@@ -1968,10 +1968,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);
                        }
@@ -1998,12 +1998,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;
 }
 
@@ -2013,7 +2013,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)
@@ -2025,7 +2025,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);
        }
 
@@ -2053,7 +2053,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);
 }
 
@@ -2104,7 +2104,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;
@@ -2135,7 +2135,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 (file)
index 0000000..6efef66
--- /dev/null
@@ -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            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__ */