diff options
author | Chris Dickens <christopher.a.dickens@gmail.com> | 2015-09-17 22:27:19 -0700 |
---|---|---|
committer | Chris Dickens <christopher.a.dickens@gmail.com> | 2015-09-20 14:48:16 -0700 |
commit | eb532c002bdd3dcd87158d5a09fe92cc89749542 (patch) | |
tree | 61bae3d7cb2861e9741dd57b962351d6b5f8f107 /libusb/os/linux_usbfs.c | |
parent | 6d5ffa0c7f454ae8827f54d81582ffff021709e6 (diff) | |
download | libusb-eb532c002bdd3dcd87158d5a09fe92cc89749542.tar.gz |
linux_usbfs: Only remove the device fd from the pollfd list once
If the file descriptor gets removed because POLLERR has been
detected, do not attempt to remove it again when closing the device.
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r-- | libusb/os/linux_usbfs.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 99136ad..a9ca506 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -144,6 +144,7 @@ struct linux_device_priv { struct linux_device_handle_priv { int fd; + int fd_removed; uint32_t caps; }; @@ -1324,9 +1325,11 @@ static int op_open(struct libusb_device_handle *handle) static void op_close(struct libusb_device_handle *dev_handle) { - int fd = _device_handle_priv(dev_handle)->fd; - usbi_remove_pollfd(HANDLE_CTX(dev_handle), fd); - close(fd); + struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle); + /* fd may have already been removed by POLLERR condition in op_handle_events() */ + if (!hpriv->fd_removed) + usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd); + close(hpriv->fd); } static int op_get_configuration(struct libusb_device_handle *handle, @@ -2595,7 +2598,11 @@ static int op_handle_events(struct libusb_context *ctx, } if (pollfd->revents & POLLERR) { + /* remove the fd from the pollfd set so that it doesn't continuously + * trigger an event, and flag that it has been removed so op_close() + * doesn't try to remove it a second time */ usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); + hpriv->fd_removed = 1; usbi_handle_disconnect(handle); /* device will still be marked as attached if hotplug monitor thread * hasn't processed remove event yet */ |