summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/core.c16
-rw-r--r--libusb/libusbi.h15
-rw-r--r--libusb/version_nano.h2
-rw-r--r--tests/umockdev.c31
4 files changed, 59 insertions, 5 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 3559470..ec429b7 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -41,6 +41,7 @@ static libusb_log_cb log_handler;
#endif
struct libusb_context *usbi_default_context;
+struct libusb_context *usbi_fallback_context;
static int default_context_refcnt;
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
static struct usbi_option default_context_options[LIBUSB_OPTION_MAX];
@@ -2284,7 +2285,7 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
usbi_mutex_static_lock(&default_context_lock);
- if (!ctx && usbi_default_context) {
+ if (!ctx && default_context_refcnt > 0) {
usbi_dbg(usbi_default_context, "reusing default context");
default_context_refcnt++;
usbi_mutex_static_unlock(&default_context_lock);
@@ -2355,9 +2356,15 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
/* Initialize hotplug after the initial enumeration is done. */
usbi_hotplug_init(_ctx);
- if (ctx)
+ if (ctx) {
*ctx = _ctx;
+ if (!usbi_fallback_context) {
+ usbi_fallback_context = _ctx;
+ usbi_warn(usbi_fallback_context, "installing new context as implicit default");
+ }
+ }
+
usbi_mutex_static_unlock(&default_context_lock);
return 0;
@@ -2430,6 +2437,8 @@ void API_EXPORTED libusb_exit(libusb_context *ctx)
if (!ctx)
usbi_default_context = NULL;
+ if (ctx == usbi_fallback_context)
+ usbi_fallback_context = NULL;
usbi_mutex_static_unlock(&default_context_lock);
@@ -2576,7 +2585,8 @@ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
#else
enum libusb_log_level ctx_level;
- ctx = usbi_get_context(ctx);
+ ctx = ctx ? ctx : usbi_default_context;
+ ctx = ctx ? ctx : usbi_fallback_context;
if (ctx)
ctx_level = ctx->debug;
else
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 7618236..b1fc88c 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -436,13 +436,26 @@ struct libusb_context {
};
extern struct libusb_context *usbi_default_context;
+extern struct libusb_context *usbi_fallback_context;
extern struct list_head active_contexts_list;
extern usbi_mutex_static_t active_contexts_lock;
static inline struct libusb_context *usbi_get_context(struct libusb_context *ctx)
{
- return ctx ? ctx : usbi_default_context;
+ static int warned = 0;
+
+ if (!ctx) {
+ ctx = usbi_default_context;
+ }
+ if (!ctx) {
+ ctx = usbi_fallback_context;
+ if (ctx && warned == 0) {
+ usbi_err(ctx, "API misuse! Using non-default context as implicit default.");
+ warned = 1;
+ }
+ }
+ return ctx;
}
enum usbi_event_flags {
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 4271170..26ed7e7 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11711
+#define LIBUSB_NANO 11712
diff --git a/tests/umockdev.c b/tests/umockdev.c
index 1eda532..488edc2 100644
--- a/tests/umockdev.c
+++ b/tests/umockdev.c
@@ -559,6 +559,32 @@ test_open_close(UMockdevTestbedFixture * fixture, UNUSED_DATA)
}
static void
+test_implicit_default(UMockdevTestbedFixture * fixture, UNUSED_DATA)
+{
+ libusb_device **devs = NULL;
+
+ clear_libusb_log(fixture, LIBUSB_LOG_LEVEL_INFO);
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
+ libusb_free_device_list(devs, TRUE);
+ assert_libusb_log_msg(fixture, LIBUSB_LOG_LEVEL_ERROR, "\\[usbi_get_context\\].*implicit default");
+
+ /* Only warns once */
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
+ libusb_free_device_list(devs, TRUE);
+ clear_libusb_log(fixture, LIBUSB_LOG_LEVEL_INFO);
+
+ libusb_init(NULL);
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
+ libusb_exit(NULL);
+
+ /* We free late, causing a warning from libusb_exit. However,
+ * we never see this warning (i.e. test success) because it is on a
+ * different context.
+ */
+ libusb_free_device_list(devs, TRUE);
+}
+
+static void
test_close_flying(UMockdevTestbedFixture * fixture, UNUSED_DATA)
{
UsbChat chat[] = {
@@ -1101,6 +1127,11 @@ main(int argc, char **argv)
test_open_close,
test_fixture_teardown);
+ g_test_add("/libusb/implicit-default", UMockdevTestbedFixture, NULL,
+ test_fixture_setup_with_canon,
+ test_implicit_default,
+ test_fixture_teardown);
+
g_test_add("/libusb/close-flying", UMockdevTestbedFixture, NULL,
test_fixture_setup_with_canon,
test_close_flying,