Backends set USBI_TRANSFER_OS_HANDLES_TIMEOUT for transfers instead.
Darwin only handles timeouts for bulk and control transfers, so the
backend now sets that flag accordingly, making libusb core handle
timeouts for interrupt and isochronous transfers. Fixes #31.
Signed-off-by: Nathan Hjelm <hjelmn@me.com>
[stuge: rework libusb_get_next_timeout() and enum usbi_transfer_flags]
[stuge: fix typo; set USBI_TRANSFER_TIMED_OUT flag correctly]
AC_DEFINE(OS_DARWIN, [], [Darwin backend])
AC_SUBST(OS_DARWIN)
AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
- AC_DEFINE(USBI_OS_HANDLES_TIMEOUT, [], [Backend handles timeout])
AC_MSG_RESULT([Darwin/MacOS X])
backend="darwin"
threads="posix"
"async cancel failed %d errno=%d", r, errno);
}
-#ifdef USBI_OS_HANDLES_TIMEOUT
-static int handle_timeouts_locked(struct libusb_context *ctx)
-{
- return 0;
-}
-static int handle_timeouts(struct libusb_context *ctx)
-{
- return 0;
-}
-#else
static int handle_timeouts_locked(struct libusb_context *ctx)
{
int r;
return 0;
/* ignore timeouts we've already handled */
- if (transfer->flags & USBI_TRANSFER_TIMED_OUT)
+ if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue;
/* if transfer has non-expired timeout, nothing more to do */
usbi_mutex_unlock(&ctx->flying_transfers_lock);
return r;
}
-#endif
#ifdef USBI_TIMERFD_AVAILABLE
static int handle_timerfd_trigger(struct libusb_context *ctx)
*/
int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
{
-#if defined(USBI_OS_HANDLES_TIMEOUT)
- return 1;
-#elif defined(USBI_TIMERFD_AVAILABLE)
+#if defined(USBI_TIMERFD_AVAILABLE)
USBI_GET_CONTEXT(ctx);
return usbi_using_timerfd(ctx);
#else
int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
struct timeval *tv)
{
-#ifndef USBI_OS_HANDLES_TIMEOUT
struct usbi_transfer *transfer;
struct timespec cur_ts;
struct timeval cur_tv;
/* find next transfer which hasn't already been processed as timed out */
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
- if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
- found = 1;
- break;
- }
+ if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
+ continue;
+
+ found = 1;
+ break;
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
}
return 1;
-#else
- return 0;
-#endif
}
/** \ingroup poll
unsigned char os_priv[0];
};
-#define USBI_TRANSFER_TIMED_OUT (1<<0)
-
enum {
USBI_CLOCK_MONOTONIC,
USBI_CLOCK_REALTIME
usbi_mutex_t lock;
};
+enum usbi_transfer_flags {
+ /* The transfer has timed out */
+ USBI_TRANSFER_TIMED_OUT = 1 << 0,
+
+ /* Set by backend submit_transfer() if the OS handles timeout */
+ USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 1
+};
+
#define __USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
((struct libusb_transfer *)(((unsigned char *)(transfer)) \
+ sizeof(struct usbi_transfer)))
ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
transfer->length, darwin_async_io_callback, itransfer);
} else {
+ itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
+
if (is_read)
ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
transfer->length, transfer->timeout, transfer->timeout,
tpriv->req.completionTimeout = transfer->timeout;
tpriv->req.noDataTimeout = transfer->timeout;
+ itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
+
/* all transfers in libusb-1.0 are async */
kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
}
static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
+ if (itransfer->flags & USBI_TRANSFER_TIMED_OUT)
+ result = kIOUSBTransactionTimeout;
+
switch (result) {
case kIOReturnUnderrun:
case kIOReturnSuccess:
return LIBUSB_TRANSFER_OVERFLOW;
case kIOUSBTransactionTimeout:
usbi_err (ITRANSFER_CTX (itransfer), "transfer error: timed out");
+ itransfer->flags |= USBI_TRANSFER_TIMED_OUT;
return LIBUSB_TRANSFER_TIMED_OUT;
default:
usbi_err (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);