I have a USB device that identifies as a HID peripheral. I communicate with it using the ReadFile
and WriteFile
Win32 API functions.
Occasionally the device gets "stuck" and does not respond, and needs to be unplugged and replugged. That's not a problem in and of itself, but it causes the call to WriteFile
to block until the device is unplugged, and that is a problem.
I have read that I can use overlapped I/O to prevent this, but it doesn't work. The call to WriteFileEx
still blocks!
Code fragment:
HANDLE hFCreateFileW(devicePath, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!WriteFileEx(hFile, buffer, length, &overlapped, nullptr))
return FALSE;
for (int elapsed = 0; !HasOverlappedIoCompleted(&overlapped); elapsed++) {
std::this_thread::sleep_for(1ms);
if (elapsed > READ_TIMEOUT_MS)
return FALSE;
}
How can I force writes to timeout instead of blocking forever?
(NOTE: The solution needs to work on all versions of Windows from XP onwards.)
According to CreateFileW documentation it is required to set FILE_FLAG_OVERLAPPED
in dwFlagsAndAttributes
argument to enable non-blocking operations for a file.
So you should open file as
HANDLE hFile = CreateFileW(devicePath, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
otherwise operations on file are still serialized even when OVERLAPPED
is passed.