static void exit_release_resources(int code) { if(tap_fd >= 0) { if_down(); while (wait(NULL) > 0) {} if_release(); while (wait(NULL) > 0) {} } if(ctx != NULL) { if(req_transfer != NULL) { libusb_cancel_transfer(req_transfer); libusb_free_transfer(req_transfer); } libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); if(fds != NULL) { free(fds); } if(devh != NULL) { libusb_release_interface(devh, 0); if (kernel_driver_active) libusb_attach_kernel_driver(devh, 0); libusb_unlock_events(ctx); libusb_close(devh); } libusb_exit(ctx); } if(logfile != NULL) { fclose(logfile); } exit(code); }
SR_PRIV int usb_source_remove(struct sr_context *ctx) { if (!ctx->usb_source_present) return SR_OK; #ifdef _WIN32 ctx->usb_thread_running = FALSE; g_mutex_unlock(&ctx->usb_mutex); libusb_unlock_events(ctx->libusb_ctx); g_thread_join(ctx->usb_thread); g_mutex_clear(&ctx->usb_mutex); sr_session_source_remove_pollfd(&ctx->usb_pollfd); CloseHandle(ctx->usb_event); #else const struct libusb_pollfd **lupfd; unsigned int i; lupfd = libusb_get_pollfds(ctx->libusb_ctx); for (i = 0; lupfd[i]; i++) sr_source_remove(lupfd[i]->fd); free(lupfd); #endif ctx->usb_source_present = FALSE; return SR_OK; }
//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::unlockEvents(State & state, Context_wrapper * wrapper){ Stack * stack = state.stack; libusb_unlock_events(wrapper->context); stack->push<bool>(true); return 1; }
/* ---- * device_handle_events() * * Function called by device_read() and device_write() to perform * the multi-thread correct event handling. * ---- */ static int device_handle_events(Open8055Card *card, int *completed) { int rc = 0; struct timeval tv; Py_BEGIN_ALLOW_THREADS while (!*completed && rc == 0) { if (libusb_try_lock_events(libusbCxt) == 0) { /* ---- * We got the event lock, so we are the event handler. * ---- */ while(!*completed) { if (!libusb_event_handling_ok(libusbCxt)) { libusb_unlock_events(libusbCxt); break; } tv.tv_sec = 1; tv.tv_usec = 0; rc = libusb_handle_events_locked(libusbCxt, &tv); if (rc != 0) break; } libusb_unlock_events(libusbCxt); } else { /* ---- * Somebody else is handling events ... wait for them. * ---- */ libusb_lock_event_waiters(libusbCxt); while (!completed) { /* ---- * Now that we have the waiters lock, recheck that * somebody is really processing events. * ---- */ if (!libusb_event_handler_active(libusbCxt)) break; /* ---- * OK to really wait now. * ---- */ libusb_wait_for_event(libusbCxt, NULL); } libusb_unlock_event_waiters(libusbCxt); } } Py_END_ALLOW_THREADS return rc; }