* non-blocking mode
* \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
-int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
- struct timeval *tv)
+int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
+ struct timeval *tv, int *completed)
{
int r;
struct timeval poll_timeout;
retry:
if (libusb_try_lock_events(ctx) == 0) {
- /* we obtained the event lock: do our own event handling */
- r = handle_events(ctx, &poll_timeout);
+ if (completed == NULL || !*completed) {
+ /* we obtained the event lock: do our own event handling */
+ usbi_dbg("doing our own event handling");
+ r = handle_events(ctx, &poll_timeout);
+ }
libusb_unlock_events(ctx);
return r;
}
* notify event completion. */
libusb_lock_event_waiters(ctx);
+ if (completed && *completed)
+ goto already_done;
+
if (!libusb_event_handler_active(ctx)) {
/* we hit a race: whoever was event handling earlier finished in the
* time it took us to reach this point. try the cycle again. */
usbi_dbg("another thread is doing event handling");
r = libusb_wait_for_event(ctx, &poll_timeout);
+
+already_done:
libusb_unlock_event_waiters(ctx);
if (r < 0)
return 0;
}
+int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
+ struct timeval *tv)
+{
+ return libusb_handle_events_timeout_completed(ctx, tv, NULL);
+}
+
/** \ingroup poll
* Handle any pending events in blocking mode. There is currently a timeout
* hardcoded at 60 seconds but we plan to make it unlimited in future. For
struct timeval tv;
tv.tv_sec = 60;
tv.tv_usec = 0;
- return libusb_handle_events_timeout(ctx, &tv);
+ return libusb_handle_events_timeout_completed(ctx, &tv, NULL);
+}
+
+int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
+ int *completed)
+{
+ struct timeval tv;
+ tv.tv_sec = 60;
+ tv.tv_usec = 0;
+ return libusb_handle_events_timeout_completed(ctx, &tv, completed);
}
/** \ingroup poll
libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
libusb_handle_events
libusb_handle_events@4 = libusb_handle_events
+ libusb_handle_events_completed
+ libusb_handle_events_completed@8 = libusb_handle_events_completed
libusb_handle_events_locked
libusb_handle_events_locked@8 = libusb_handle_events_locked
libusb_handle_events_timeout
libusb_handle_events_timeout@8 = libusb_handle_events_timeout
+ libusb_handle_events_timeout_completed
+ libusb_handle_events_timeout_completed@12 = libusb_handle_events_timeout_completed
libusb_init
libusb_init@4 = libusb_init
libusb_interrupt_transfer
int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx,
struct timeval *tv);
+int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx,
+ struct timeval *tv, int *completed);
int LIBUSB_CALL libusb_handle_events(libusb_context *ctx);
+int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed);
int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx,
struct timeval *tv);
int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx);
}
while (!completed) {
- r = libusb_handle_events(HANDLE_CTX(dev_handle));
+ r = libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed);
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
+ if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
break;
libusb_free_transfer(transfer);
return r;
}
while (!completed) {
- r = libusb_handle_events(HANDLE_CTX(dev_handle));
+ r = libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed);
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
+ if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
break;
libusb_free_transfer(transfer);
return r;