SDL: hidapi, libusb: backport read_thread indefinite loop fix from mainstream (14bf8)

From 14bf8237c1bd67e30ddfd461e8fed69c1298b8a0 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 28 Sep 2022 17:40:10 +0300
Subject: [PATCH] hidapi, libusb: backport read_thread indefinite loop fix from
 mainstream

Mainstream commit:
https://github.com/libusb/hidapi/commit/5ce9051e2f2e65013485bc4c83897610df82f3c9
(cherry picked from commit 8bcbdc706c44ec2a36c2c94ec45be49c8b8373e5)
---
 src/hidapi/SDL_hidapi.c | 4 ++++
 src/hidapi/libusb/hid.c | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index 8234963802b3..9d3bd429c1cf 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -737,6 +737,7 @@ static struct
     );
     int (LIBUSB_CALL *handle_events)(libusb_context *ctx);
     int (LIBUSB_CALL *handle_events_completed)(libusb_context *ctx, int *completed);
+    const char * (LIBUSB_CALL *error_name)(int errcode);
 } libusb_ctx;
 
 #define libusb_init                            libusb_ctx.init
@@ -765,6 +766,7 @@ static struct
 #define libusb_interrupt_transfer              libusb_ctx.interrupt_transfer
 #define libusb_handle_events                   libusb_ctx.handle_events
 #define libusb_handle_events_completed         libusb_ctx.handle_events_completed
+#define libusb_error_name                      libusb_ctx.error_name
 
 #define hid_device                      LIBUSB_hid_device
 #define hid_device_                     LIBUSB_hid_device_
@@ -842,6 +844,7 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
 #undef libusb_interrupt_transfer
 #undef libusb_handle_events
 #undef libusb_handle_events_completed
+#undef libusb_error_name
 
 #undef hid_device
 #undef hid_device_
@@ -1112,6 +1115,7 @@ int SDL_hid_init(void)
             LOAD_LIBUSB_SYMBOL(interrupt_transfer)
             LOAD_LIBUSB_SYMBOL(handle_events)
             LOAD_LIBUSB_SYMBOL(handle_events_completed)
+            LOAD_LIBUSB_SYMBOL(error_name)
             #undef LOAD_LIBUSB_SYMBOL
 
             if (!loaded) {
diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c
index dbcd4fa3bdf6..ad2676ba899d 100644
--- a/src/hidapi/libusb/hid.c
+++ b/src/hidapi/libusb/hid.c
@@ -1016,6 +1016,7 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
 
 static int SDLCALL read_thread(void *param)
 {
+	int res;
 	hid_device *dev = (hid_device *)param;
 	uint8_t *buf;
 	const size_t length = dev->input_ep_max_packet_size;
@@ -1034,14 +1035,18 @@ static int SDLCALL read_thread(void *param)
 
 	/* Make the first submission. Further submissions are made
 	   from inside read_callback() */
-	libusb_submit_transfer(dev->transfer);
+	res = libusb_submit_transfer(dev->transfer);
+	if(res < 0) {
+                LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res));
+                dev->shutdown_thread = 1;
+                dev->transfer_loop_finished = 1;
+	}
 
 	/* Notify the main thread that the read thread is up and running. */
 	SDL_WaitThreadBarrier(&dev->barrier);
 
 	/* Handle all the events. */
 	while (!dev->shutdown_thread) {
-		int res;
 		res = libusb_handle_events(usb_context);
 		if (res < 0) {
 			/* There was an error. */