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

Reply via email to