summaryrefslogtreecommitdiff
path: root/libusb/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusb/core.c')
-rw-r--r--libusb/core.c129
1 files changed, 66 insertions, 63 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 4e812ed..de16ea2 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -18,11 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@@ -53,7 +49,7 @@ const struct usbi_os_backend * const usbi_backend = &windows_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
@@ -518,7 +514,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) {
free(dev);
return NULL;
@@ -529,9 +525,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;
}
@@ -571,13 +567,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, struct libusb_device)
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;
}
@@ -812,9 +808,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;
}
@@ -830,9 +826,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);
@@ -840,9 +836,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);
}
@@ -880,7 +876,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) {
free(_handle);
return LIBUSB_ERROR_OTHER;
@@ -893,14 +889,14 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
r = usbi_backend->open(_handle);
if (r < 0) {
libusb_unref_device(dev);
- pthread_mutex_destroy(&_handle->lock);
+ usbi_mutex_destroy(&_handle->lock);
free(_handle);
return (int)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;
@@ -912,17 +908,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 = _libusb_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;
}
@@ -935,9 +931,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);
@@ -999,13 +995,13 @@ 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);
- pthread_mutex_destroy(&dev_handle->lock);
+ usbi_mutex_destroy(&dev_handle->lock);
free(dev_handle);
}
@@ -1039,18 +1035,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 = _libusb_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;
}
@@ -1066,9 +1062,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);
@@ -1215,7 +1211,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;
@@ -1224,7 +1220,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;
}
@@ -1252,7 +1248,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;
@@ -1263,7 +1259,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;
}
@@ -1296,12 +1292,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);
@@ -1472,12 +1468,23 @@ API_EXPORTED void libusb_set_debug(libusb_context *ctx, int level)
API_EXPORTED int libusb_init(libusb_context **context)
{
char *dbg = getenv("LIBUSB_DEBUG");
- struct libusb_context *ctx = malloc(sizeof(*ctx));
+ struct libusb_context *ctx;
int r;
- if (!ctx)
+ usbi_mutex_static_lock(&default_context_lock);
+ if (!context && usbi_default_context) {
+ usbi_mutex_static_unlock(&default_context_lock);
+ return 0; /* using default; nothing to do. */
+ }
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx) {
+ usbi_mutex_static_unlock(&default_context_lock);
return LIBUSB_ERROR_NO_MEM;
+ }
memset(ctx, 0, sizeof(*ctx));
+#ifdef USBI_TIMERFD_AVAILABLE
+ ctx->timerfd = -1;
+#endif
if (dbg) {
ctx->debug = atoi(dbg);
@@ -1487,17 +1494,17 @@ API_EXPORTED int libusb_init(libusb_context **context)
usbi_dbg("");
+ 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);
+
if (usbi_backend->init) {
r = usbi_backend->init(ctx);
if (r)
goto err;
}
- pthread_mutex_init(&ctx->usb_devs_lock, NULL);
- pthread_mutex_init(&ctx->open_devs_lock, NULL);
- list_init(&ctx->usb_devs);
- list_init(&ctx->open_devs);
-
r = usbi_io_init(ctx);
if (r < 0) {
if (usbi_backend->exit)
@@ -1505,24 +1512,20 @@ API_EXPORTED int libusb_init(libusb_context **context)
goto err;
}
- pthread_mutex_lock(&default_context_lock);
if (!usbi_default_context) {
usbi_dbg("created default context");
usbi_default_context = ctx;
- } else if (!context) {
- pthread_mutex_unlock(&default_context_lock);
- libusb_exit(ctx); /* free superfluous context; use default context */
- return 0;
}
- pthread_mutex_unlock(&default_context_lock);
+ usbi_mutex_static_unlock(&default_context_lock);
if (context)
*context = ctx;
return 0;
err:
- pthread_mutex_destroy(&ctx->open_devs_lock);
- pthread_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_static_unlock(&default_context_lock);
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
free(ctx);
return r;
}
@@ -1546,15 +1549,15 @@ 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);
- pthread_mutex_destroy(&ctx->open_devs_lock);
- pthread_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
free(ctx);
}
@@ -1617,8 +1620,8 @@ void usbi_log(struct libusb_context *ctx, enum usbi_log_level level,
* Returns a constant string with an English short description of the given
* error code. The caller should never free() the returned pointer since it
* points to a constant string.
- * The returned string is encoded in ASCII form and always starts with a capital
- * letter and ends without any dot.
+ * The returned string is encoded in ASCII form and always starts with a
+ * capital letter and ends without any dot.
* \param errcode the error code whose description is desired
* \returns a short description of the error code in English
*/