//For events on USB socket void usb_monitor_usb_event_cb(void *ptr, int32_t fd, uint32_t events) { struct timeval tv = {0 ,0}; libusb_unlock_events(NULL); libusb_handle_events_timeout_completed(NULL, &tv, NULL); libusb_lock_events(NULL); }
static void do_close(struct libusb_context *ctx, struct libusb_device_handle *dev_handle) { struct usbi_transfer *itransfer; struct usbi_transfer *tmp; libusb_lock_events(ctx); usbi_mutex_lock(&ctx->flying_transfers_lock); list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); if (transfer->dev_handle != dev_handle) continue; if (!(itransfer->flags & USBI_TRANSFER_DEVICE_DISAPPEARED)) { usbi_err(ctx, "Device handle closed while transfer was still being processed, but the device is still connected as far as we know"); if (itransfer->flags & USBI_TRANSFER_CANCELLING) usbi_warn(ctx, "A cancellation for an in-flight transfer hasn't completed but closing the device handle"); else usbi_err(ctx, "A cancellation hasn't even been scheduled on the transfer for which the device is closing"); } usbi_mutex_lock(&itransfer->lock); list_del(&itransfer->list); transfer->dev_handle = NULL; usbi_mutex_unlock(&itransfer->lock); usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed", transfer, dev_handle); } usbi_mutex_unlock(&ctx->flying_transfers_lock); libusb_unlock_events(ctx); usbi_mutex_lock(&ctx->open_devs_lock); list_del(&dev_handle->list); usbi_mutex_unlock(&ctx->open_devs_lock); usbi_backend->close(dev_handle); libusb_unref_device(dev_handle->dev); usbi_mutex_destroy(&dev_handle->lock); free(dev_handle); }
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) { struct libusb_context *ctx; unsigned char dummy = 1; ssize_t r; if (!dev_handle) return; usbi_dbg(""); ctx = HANDLE_CTX(dev_handle); usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify++; usbi_mutex_unlock(&ctx->pollfd_modify_lock); r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); if (r <= 0) { usbi_warn(ctx, "internal signalling write failed, closing anyway"); do_close(ctx, dev_handle); usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; usbi_mutex_unlock(&ctx->pollfd_modify_lock); return; } libusb_lock_events(ctx); r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); if (r <= 0) usbi_warn(ctx, "internal signalling read failed, closing anyway"); do_close(ctx, dev_handle); usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; usbi_mutex_unlock(&ctx->pollfd_modify_lock); libusb_unlock_events(ctx); }
//This function is called for every iteration + every second. Latter is needed //in case of restart void usb_monitor_itr_cb(void *ptr) { struct usb_monitor_ctx *ctx = ptr; struct timeval tv = {0 ,0}; //First, check for any of libusb's timers. We are incontrol of timer, so no //need for this function to block libusb_unlock_events(NULL); libusb_handle_events_timeout_completed(NULL, &tv, NULL); libusb_lock_events(NULL); //Check if we have any pending timeouts //TODO: Consider using the event loop timer queue for this usb_monitor_check_timeouts(ctx); }
void usbi_fd_notification(struct libusb_context *ctx) { unsigned char dummy = 1; ssize_t r; if (ctx == NULL) return; usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify++; usbi_mutex_unlock(&ctx->pollfd_modify_lock); r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); if (r <= 0) { usbi_warn(ctx, "internal signalling write failed"); usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; usbi_mutex_unlock(&ctx->pollfd_modify_lock); return; } libusb_lock_events(ctx); r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); if (r <= 0) usbi_warn(ctx, "internal signalling read failed"); usbi_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify--; usbi_mutex_unlock(&ctx->pollfd_modify_lock); libusb_unlock_events(ctx); }
int Context::lockEvents(State & state, Context_wrapper * wrapper){ Stack * stack = state.stack; libusb_lock_events(wrapper->context); stack->push<bool>(true); return 1; }