darwin: Transition to use new transfer completion API
authorChris Dickens <christopher.a.dickens@gmail.com>
Wed, 21 Jan 2015 08:18:41 +0000 (00:18 -0800)
committerChris Dickens <christopher.a.dickens@gmail.com>
Tue, 27 Jan 2015 02:57:29 +0000 (18:57 -0800)
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/os/darwin_usb.c
libusb/os/darwin_usb.h
libusb/version_nano.h

index 19174b1..43d03cd 100644 (file)
@@ -973,14 +973,6 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
   /* device opened successfully */
   dpriv->open_count++;
 
-  /* create a file descriptor for notifications */
-  pipe (priv->fds);
-
-  /* set the pipe to be non-blocking */
-  fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
-
-  usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
-
   usbi_dbg ("device open for access");
 
   return 0;
@@ -1024,13 +1016,6 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
       }
     }
   }
-
-  /* file descriptors are maintained per-instance */
-  usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
-  close (priv->fds[1]);
-  close (priv->fds[0]);
-
-  priv->fds[0] = priv->fds[1] = -1;
 }
 
 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
@@ -1762,8 +1747,7 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
   struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
-  struct darwin_msg_async_io_complete message = {.itransfer = itransfer, .result = result,
-                                                 .size = (UInt32) (uintptr_t) arg0};
+  struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
 
   usbi_dbg ("an async io operation has completed");
 
@@ -1777,8 +1761,11 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
     (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
   }
 
-  /* send a completion message to the device's file descriptor */
-  write (priv->fds[1], &message, sizeof (message));
+  tpriv->result = result;
+  tpriv->size = (UInt32) (uintptr_t) arg0;
+
+  /* signal the core that this transfer is complete */
+  usbi_signal_transfer_completion(itransfer);
 }
 
 static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
@@ -1807,7 +1794,7 @@ static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_
   }
 }
 
-static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
+static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
   int isIsoc      = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
@@ -1818,13 +1805,13 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
 
   if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
-    return;
+    return LIBUSB_ERROR_INVALID_PARAM;
   }
 
   usbi_dbg ("handling %s completion with kernel status %d",
-             isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", result);
+             isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
 
-  if (kIOReturnSuccess == result || kIOReturnUnderrun == result) {
+  if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
     if (isIsoc && tpriv->isoc_framelist) {
       /* copy isochronous results back */
 
@@ -1834,48 +1821,11 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
         lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
       }
     } else if (!isIsoc)
-      itransfer->transferred += io_size;
+      itransfer->transferred += tpriv->io_size;
   }
 
   /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
-  usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
-}
-
-static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
-  struct darwin_msg_async_io_complete message;
-  POLL_NFDS_TYPE i = 0;
-  ssize_t ret;
-
-  usbi_mutex_lock(&ctx->open_devs_lock);
-
-  for (i = 0; i < nfds && num_ready > 0; i++) {
-    struct pollfd *pollfd = &fds[i];
-
-    usbi_dbg ("checking fd %i with revents = %x", pollfd->fd, pollfd->revents);
-
-    if (!pollfd->revents)
-      continue;
-
-    num_ready--;
-
-    if (pollfd->revents & POLLERR) {
-      /* this probably will never happen so ignore the error an move on. */
-      continue;
-    }
-
-    /* there is only one type of message */
-    ret = read (pollfd->fd, &message, sizeof (message));
-    if (ret < (ssize_t) sizeof (message)) {
-      usbi_dbg ("WARNING: short read on async io completion pipe\n");
-      continue;
-    }
-
-    darwin_handle_callback (message.itransfer, message.result, message.size);
-  }
-
-  usbi_mutex_unlock(&ctx->open_devs_lock);
-
-  return 0;
+  return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
 }
 
 static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
@@ -1998,7 +1948,7 @@ const struct usbi_os_backend darwin_backend = {
         .cancel_transfer = darwin_cancel_transfer,
         .clear_transfer_priv = darwin_clear_transfer_priv,
 
-        .handle_events = op_handle_events,
+        .handle_transfer_completion = darwin_handle_transfer_completion,
 
         .clock_gettime = darwin_clock_gettime,
 
index 066197b..4cf28bf 100644 (file)
@@ -130,7 +130,6 @@ struct darwin_device_priv {
 struct darwin_device_handle_priv {
   int                  is_open;
   CFRunLoopSourceRef   cfSource;
-  int                  fds[2];
 
   struct darwin_interface {
     usb_interface_t    **interface;
@@ -150,11 +149,8 @@ struct darwin_transfer_priv {
   IOUSBDevRequestTO req;
 
   /* Bulk */
-};
 
-/* structure for signaling io completion */
-struct darwin_msg_async_io_complete {
-  struct usbi_transfer *itransfer;
+  /* Completion status */
   IOReturn result;
   UInt32 size;
 };
index b9f504c..c5e60a2 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10954
+#define LIBUSB_NANO 10955