@@ -253,14 +253,28 @@ def _dev_read_thread(hid_device):
253253 hid_device .handle , REMOVAL_CALLBACK , ctypes .py_object (hid_device )
254254 )
255255
256- # Run the run loop
257- run_loop_run_result = cf .CFRunLoopRunInMode (
258- K_CF_RUNLOOP_DEFAULT_MODE , 4 , True # Timeout in seconds
259- ) # Return after source handled
260-
261- # log any unexpected run loop exit
262- if run_loop_run_result != K_CF_RUN_LOOP_RUN_HANDLED_SOURCE :
263- logger .error ("Unexpected run loop exit code: %d" , run_loop_run_result )
256+ max_retries = 2 # Maximum number of run loop retries
257+ retries = 0
258+
259+ while retries < max_retries :
260+ # Run the run loop
261+ run_loop_run_result = cf .CFRunLoopRunInMode (
262+ K_CF_RUNLOOP_DEFAULT_MODE , 4 , True # Timeout in seconds
263+ ) # Return after source handled
264+
265+ received_data = not hid_device .read_queue .empty ()
266+ if run_loop_run_result == K_CF_RUN_LOOP_RUN_HANDLED_SOURCE :
267+ if received_data :
268+ # Return when data has been received
269+ break
270+ else :
271+ # Retry running the run loop if data has not been received yet
272+ logger .debug ("Read queue empty after HANDLE_SOURCE, attempting retry" )
273+ retries += 1
274+ else :
275+ # log any unexpected run loop exit
276+ logger .error ("Unexpected run loop exit code: %d" , run_loop_run_result )
277+ break
264278
265279 # Unschedule from run loop
266280 iokit .IOHIDDeviceUnscheduleFromRunLoop (
0 commit comments