void usbi_hotplug_match(struct libusb_device *dev, libusb_hotplug_event event) { struct libusb_hotplug_callback *hotplug_cb, *next; struct libusb_context *ctx = dev->ctx; int ret; usbi_mutex_lock(&ctx->hotplug_cbs_lock); list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { usbi_mutex_unlock(&ctx->hotplug_cbs_lock); ret = usbi_hotplug_match_cb (dev, event, hotplug_cb); usbi_mutex_lock(&ctx->hotplug_cbs_lock); if (ret) { list_del(&hotplug_cb->list); free(hotplug_cb); } } usbi_mutex_unlock(&ctx->hotplug_cbs_lock); /* loop through and disconnect all open handles for this device */ if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { struct libusb_device_handle *handle; usbi_mutex_lock(&ctx->open_devs_lock); list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { if (dev == handle->dev) { usbi_handle_disconnect (handle); } } usbi_mutex_unlock(&ctx->open_devs_lock); } }
int obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready) { struct libusb_device_handle *handle; struct handle_priv *hpriv = NULL; struct usbi_transfer *itransfer; struct pollfd *pollfd; int i, err = 0; usbi_dbg(""); pthread_mutex_lock(&ctx->open_devs_lock); for (i = 0; i < nfds && num_ready > 0; i++) { pollfd = &fds[i]; if (!pollfd->revents) continue; hpriv = NULL; num_ready--; list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { hpriv = (struct handle_priv *)handle->os_priv; if (hpriv->pipe[0] == pollfd->fd) break; hpriv = NULL; } if (NULL == hpriv) { usbi_dbg("fd %d is not an event pipe!", pollfd->fd); err = ENOENT; break; } if (pollfd->revents & POLLERR) { usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); usbi_handle_disconnect(handle); continue; } if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) { err = errno; break; } if ((err = usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED))) break; } pthread_mutex_unlock(&ctx->open_devs_lock); if (err) return _errno_to_libusb(err); return (LIBUSB_SUCCESS); }