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
[email protected]
https://lists.sourceforge.net/lists/listinfo/libusbx-devel