This change makes the Windows and Windows CE backend pre-reserve pollfds before submitting transfers. This allows these backends to correctly handle failure to reserve pollfds.
Prior to this change both backends ignored the return value from usbi_add_pollfds. --- libusb/os/wince_usb.c | 13 ++++++++++++- libusb/os/windows_usb.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c index 9957b8e..d1c3432 100644 --- a/libusb/os/wince_usb.c +++ b/libusb/os/wince_usb.c @@ -618,6 +618,13 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer HANDLE eventHandle; PUKW_CONTROL_HEADER setup = NULL; const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL; + struct usbi_pollfd* ipollfd; + + ret = usbi_reserve_pollfd(ctx, &ipollfd); + if (ret != LIBUSB_SUCCESS) { + usbi_err(ctx, "Failed to reserve pollfd for async transfer"); + return ret; + } transfer_priv->pollable_fd = INVALID_WINFD; if (control_transfer) { @@ -632,12 +639,14 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); if (eventHandle == NULL) { usbi_err(ctx, "Failed to create event for async transfer"); + usbi_unreserve_pollfd(ctx, ipollfd); return LIBUSB_ERROR_NO_MEM; } wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer); if (wfd.handle == INVALID_HANDLE_VALUE) { CloseHandle(eventHandle); + usbi_unreserve_pollfd(ctx, ipollfd); return LIBUSB_ERROR_NO_MEM; } @@ -657,9 +666,11 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer usbi_err(ctx, "UkwIssue%sTransfer failed: error %d", control_transfer ? "Control" : "Bulk", GetLastError()); wince_clear_transfer_priv(itransfer); + usbi_unreserve_pollfd(ctx, ipollfd); return libusbErr; } - usbi_add_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, direction_in ? POLLIN : POLLOUT); + usbi_add_reserved_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, + direction_in ? POLLIN : POLLOUT, ipollfd); itransfer->flags |= USBI_TRANSFER_UPDATED_FDS; return LIBUSB_SUCCESS; diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 26cb7f8..a9090e4 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -1926,14 +1926,22 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); int r; + struct usbi_pollfd* ipollfd; + + r = usbi_reserve_pollfd(ctx, &ipollfd); + if (r != LIBUSB_SUCCESS) { + usbi_err(ctx, "Failed to reserve pollfd for async transfer"); + return r; + } r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer); if (r != LIBUSB_SUCCESS) { + usbi_unreserve_pollfd(ctx, ipollfd); return r; } - usbi_add_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, - (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT)); + usbi_add_reserved_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, + (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT), ipollfd); itransfer->flags |= USBI_TRANSFER_UPDATED_FDS; return LIBUSB_SUCCESS; @@ -1946,14 +1954,22 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); int r; + struct usbi_pollfd* ipollfd; + + r = usbi_reserve_pollfd(ctx, &ipollfd); + if (r != LIBUSB_SUCCESS) { + usbi_err(ctx, "Failed to reserve pollfd for async transfer"); + return r; + } r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer); if (r != LIBUSB_SUCCESS) { + usbi_unreserve_pollfd(ctx, ipollfd); return r; } - usbi_add_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, - (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT)); + usbi_add_reserved_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, + (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT), ipollfd); itransfer->flags |= USBI_TRANSFER_UPDATED_FDS; return LIBUSB_SUCCESS; @@ -1966,13 +1982,22 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); int r; + struct usbi_pollfd* ipollfd; + + r = usbi_reserve_pollfd(ctx, &ipollfd); + if (r != LIBUSB_SUCCESS) { + usbi_err(ctx, "Failed to reserve pollfd for async transfer"); + return r; + } r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer); if (r != LIBUSB_SUCCESS) { + usbi_unreserve_pollfd(ctx, ipollfd); return r; } - usbi_add_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, POLLIN); + usbi_add_reserved_pollfd(ctx, transfer_priv->pollable_fd.overlapped->hEvent, + POLLIN, ipollfd); itransfer->flags |= USBI_TRANSFER_UPDATED_FDS; return LIBUSB_SUCCESS; -- 1.7.9.5 ------------------------------------------------------------------------------ This SF.net email is sponsored by Windows: Build for Windows Store. http://p.sf.net/sfu/windows-dev2dev _______________________________________________ libusbx-devel mailing list libusbx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libusbx-devel