Ludovic Rousseau wrote:
> From what I can understand op_close() in libusb/os/linux_usbfs.c is calling
> usbi_remove_pollfd(HANDLE_CTX(dev_handle), fd);
> And this should remove any pollfd associated wit the dev_handle context.
Thanks a lot for the detailed diagnosis. You have indeed found a race
condition, and raised attention to a few of them.
Essentially the problem is that devices can be closed by one thread when
another is in event handling (in one of several stages).
There are problems even more basic than the one you have found. For
example in io.c : handle_events()
The logic is approximately:
1. Lock poll fds
2. Collect poll fds into poll() pollfd structure
3. Unlock poll fds
4. call poll() on those descriptors
The device can be closed between 3 and 4, in which case the fd will be
invalid. Even worse, the device could be closed and something else could
be opened, reusing the fd, meaning we end up polling something else.
The solution needs to involve libusb_close() not actually closing stuff
while polling is happening, but I feel that the solution isn't simply
waiting until event handling stops (something may have an infinite
timeout), so instead we need a way of libusb signalling to itself that
event handling should be paused for a while, so we'd have some kind of
control pipe that is also polled which libusb_close could signal the
event handling thread on ...
It's a bit complicated. I'll work on it.