Recently I've but a victim of slow HID read speeds in recent versions of Windows 10. I've had to increase my timeout values from 2ms all the way up to 50ms to prevent losing data. The real problem for me with long timeout values is that I need to read realtime data from up four USB HID devices.
As a work around, I'm trying to implement the calls to rawhid_recv on separate threads for each USB device. I was looking over the rawhid_recv code, and I see that there is a mutex in there. I'm guessing that's going to slow down my code? Does the mutex need to be there? If I ensure that multiple threads don't read from the same USB, can I just remove it? The code for rawhid_recv, most likely written by Paul, is below. I'd love to hear any insight you can offer.
As a work around, I'm trying to implement the calls to rawhid_recv on separate threads for each USB device. I was looking over the rawhid_recv code, and I see that there is a mutex in there. I'm guessing that's going to slow down my code? Does the mutex need to be there? If I ensure that multiple threads don't read from the same USB, can I just remove it? The code for rawhid_recv, most likely written by Paul, is below. I'd love to hear any insight you can offer.
Code:
int rawhid_recv(int num, void *buf, int len, int timeout) {
hid_t *hid;
unsigned char tmpbuf[516];
OVERLAPPED ov;
DWORD n, r;
if (sizeof(tmpbuf) < len + 1) return -1;
hid = get_hid(num);
if (!hid || !hid->open) return -1;
EnterCriticalSection(&rx_mutex);
ResetEvent(&rx_event);
memset(&ov, 0, sizeof(ov));
ov.hEvent = rx_event;
if (!ReadFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
if (GetLastError() != ERROR_IO_PENDING) goto return_error;
r = WaitForSingleObject(rx_event, timeout);
if (r == WAIT_TIMEOUT) goto return_timeout;
if (r != WAIT_OBJECT_0) goto return_error;
}
if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
LeaveCriticalSection(&rx_mutex);
if (n <= 0) return -1;
n--;
if (n > len) n = len;
memcpy(buf, tmpbuf + 1, n);
return n;
return_timeout:
CancelIo(hid->handle);
LeaveCriticalSection(&rx_mutex);
return 0;
return_error:
print_win32_err();
LeaveCriticalSection(&rx_mutex);
return -1;
}