/** \ingroup poll * Handle any pending events. * * libusb determines "pending events" by checking if any timeouts have expired * and by checking the set of file descriptors for activity. * * If a zero timeval is passed, this function will handle any already-pending * events and then immediately return in non-blocking style. * * If a non-zero timeval is passed and no events are currently pending, this * function will block waiting for events to handle up until the specified * timeout. If an event arrives or a signal is raised, this function will * return early. * * If the parameter completed is not NULL then <em>after obtaining the event * handling lock</em> this function will return immediately if the integer * pointed to is not 0. This allows for race free waiting for the completion * of a specific transfer. * * \param ctx the context to operate on, or NULL for the default context * \param tv the maximum time to block waiting for events, or an all zero * timeval struct for non-blocking mode * \param completed pointer to completion integer to check, or NULL * \returns 0 on success, or a LIBUSB_ERROR code on failure * \ref mtasync */ int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx, struct timeval *tv, int *completed) { int r; struct timeval poll_timeout; USBI_GET_CONTEXT(ctx); r = get_next_timeout(ctx, tv, &poll_timeout); if (r) { /* timeout already expired */ return handle_timeouts(ctx); } retry: if (libusb_try_lock_events(ctx) == 0) { 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; } /* another thread is doing event handling. wait for thread events that * 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. */ libusb_unlock_event_waiters(ctx); usbi_dbg("event handler was active but went away, retrying"); goto retry; } usbi_dbg("another thread is doing event handling"); r = libusb_wait_for_event(ctx, &poll_timeout); already_done: libusb_unlock_event_waiters(ctx); if (UNLIKELY(r < 0)) return r; else if (r == 1) return handle_timeouts(ctx); else return 0; }
goto A;可以跳转到函数内部的A的标识出,不管出现在前还是后
最新推荐文章于 2024-07-01 15:28:51 发布