diff options
-rw-r--r-- | libusb/core.c | 16 | ||||
-rw-r--r-- | libusb/libusbi.h | 15 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 | ||||
-rw-r--r-- | tests/umockdev.c | 31 |
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, |