mirror of
https://github.com/shadps4-emu/ext-libusb.git
synced 2026-01-31 00:55:21 +01:00
core: Install first context as implicit default (and warn about its use)
There was a behaviour change in libusb 1.0.25 which triggers issues when the API is misused. This caused for instance gutenprint to crash, see https://bugzilla.redhat.com/show_bug.cgi?id=2055504 This seems to affect several applications "out in the wild". For now, work around this by installing an implicit default. But, change the code to log an error in case this "feature" is being used. This will allow some grace time for developers to fix their applications, before we at a later point revert to the stricter behaviour. Fixes #1089
This commit is contained in:
committed by
Tormod Volden
parent
66d3849974
commit
6b29aeb9ca
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define LIBUSB_NANO 11711
|
||||
#define LIBUSB_NANO 11712
|
||||
|
||||
@@ -558,6 +558,32 @@ test_open_close(UMockdevTestbedFixture * fixture, UNUSED_DATA)
|
||||
libusb_close(handle);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user