Commit 8bcbdc706c44ec2a36c2c94ec45be49c8b8373e5

Ozkan Sezer 2022-09-28T17:40:10

hidapi, libusb: backport read_thread indefinite loop fix from mainstream Mainstream commit: https://github.com/libusb/hidapi/commit/5ce9051e2f2e65013485bc4c83897610df82f3c9

diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index d732b5f..d62acb0 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -738,6 +738,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
@@ -766,6 +767,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_
@@ -843,6 +845,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_
@@ -1109,6 +1112,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 a84a0d2..e86aa51 100644
--- a/src/hidapi/libusb/hid.c
+++ b/src/hidapi/libusb/hid.c
@@ -1051,6 +1051,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;
@@ -1069,14 +1070,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. */