From 11fed40c794f6c29b6d288b63eceaffbf67f02e6 Mon Sep 17 00:00:00 2001 From: gblues Date: Sat, 30 Dec 2017 16:36:54 -0800 Subject: [PATCH 1/2] Fix another crash bug in joypad_connect == DETAILS I fixed a similar bug in a past commit, with the same root cause: making assumptions about the length of the array. - Add validation to joypad_connection_init() so that if >MAX_USERS is requested, a warning is logged and only MAX_USERS is allocated. - Rewrote the iteration routines so they strictly use the joypad_is_end_of_list() method to detect the end. --- input/connect/joypad_connection.c | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index b1f9a360c7..7293a2c4be 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -24,22 +24,22 @@ #include "joypad_connection.h" +static bool joypad_is_end_of_list(joypad_connection_t *pad); + int pad_connection_find_vacant_pad(joypad_connection_t *joyconn) { - unsigned i; + unsigned i; - if (!joyconn) - return -1; + if (!joyconn) + return -1; - for (i = 0; i < MAX_USERS; i++) - { - joypad_connection_t *conn = &joyconn[i]; + for (i = 0; !joypad_is_end_of_list(&joyconn[i]); i++) + { + if(!joyconn[i].connected) + return i; + } - if (conn && !conn->connected) - return i; - } - - return -1; + return -1; } static void set_end_of_list(joypad_connection_t *list, unsigned end) @@ -62,6 +62,14 @@ static bool joypad_is_end_of_list(joypad_connection_t *pad) { joypad_connection_t *pad_connection_init(unsigned pads) { unsigned i; + + if(pads > MAX_USERS) + { + RARCH_WARN("[joypad] invalid number of pads requested (%d), using default (%d)\n", + pads, MAX_USERS); + pads = MAX_USERS; + } + joypad_connection_t *joyconn = (joypad_connection_t*) calloc(pads+1, sizeof(joypad_connection_t)); @@ -226,13 +234,8 @@ void pad_connection_destroy(joypad_connection_t *joyconn) { unsigned i; - for (i = 0; i < MAX_USERS; i ++) - { - if(joypad_is_end_of_list(&joyconn[i])) - break; - + for (i = 0; !joypad_is_end_of_list(&joyconn[i]); i ++) pad_connection_pad_deinit(&joyconn[i], i); - } free(joyconn); } From c2d2fe971e10ce394e5fadbdf8ff057b419c400a Mon Sep 17 00:00:00 2001 From: gblues Date: Sat, 30 Dec 2017 20:59:07 -0800 Subject: [PATCH 2/2] Add timeout for HID thread shutdown == DETAILS If a call to HIDRead() ends up blocking indefinitely, it will cause the shutdown process to wait forever. To avoid a deadlock, I've put in a retry counter so that it will give up after 5s and print a warning to the log. --- wiiu/input/wiiu_hid.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wiiu/input/wiiu_hid.c b/wiiu/input/wiiu_hid.c index 1c93c3cde9..f62eea43f9 100644 --- a/wiiu/input/wiiu_hid.c +++ b/wiiu/input/wiiu_hid.c @@ -425,6 +425,7 @@ static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error, */ static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack) { int incomplete = 0; + int retries = 0; wiiu_adapter_t *adapter; RARCH_LOG("Waiting for in-flight reads to finish.\n"); do { @@ -446,8 +447,11 @@ static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack) { } OSFastMutex_Unlock(&(adapters.lock)); if(incomplete) { - RARCH_LOG("%d unfinished adapters found, waiting 1ms\n", incomplete); - usleep(1000); + usleep(5000); + } + if(++retries >= 1000) { + RARCH_WARN("[hid]: timed out waiting for in-flight read to finish.\n"); + incomplete = 0; } } while(incomplete); RARCH_LOG("All in-flight reads complete.\n");