Notifications for changes to the fd set
authorDaniel Drake <dsd@gentoo.org>
Tue, 26 Feb 2008 22:11:34 +0000 (22:11 +0000)
committerDaniel Drake <dsd@gentoo.org>
Tue, 26 Feb 2008 22:39:28 +0000 (22:39 +0000)
Applications can now be notified when they should start and stop polling
new file descriptors.

TODO
libusb/core.c
libusb/io.c
libusb/libusb.h
libusb/libusbi.h

diff --git a/TODO b/TODO
index c4deecc..68adc12 100644 (file)
--- a/TODO
+++ b/TODO
@@ -23,3 +23,4 @@ devh in general
 urbh in general (should this be a transfer handle?)
 find/get devices API
 config struct/function naming
+typedef _cb or _cb_fn or _cb_t?
index e9939f4..1560567 100644 (file)
@@ -238,12 +238,14 @@ API_EXPORTED struct libusb_dev_handle *libusb_open(struct libusb_dev *dev)
        devh->fd = fd;
        devh->dev = dev;
        list_add(&devh->list, &open_devs);
+       usbi_add_pollfd(fd, POLLOUT);
        return devh;
 }
 
 static void do_close(struct libusb_dev_handle *devh)
 {
-       close(devh->fd);        
+       usbi_remove_pollfd(devh->fd);
+       close(devh->fd);
 }
 
 API_EXPORTED void libusb_close(struct libusb_dev_handle *devh)
@@ -320,6 +322,8 @@ API_EXPORTED size_t libusb_get_pollfds(struct libusb_pollfd **pollfds)
 
        /* create array */
        ret = calloc(cnt, sizeof(struct libusb_pollfd));
+       if (!ret)
+               return -ENOMEM;
 
        /* add fds */
        list_for_each_entry(devh, &open_devs, list) {
index ae572ab..07a7bf0 100644 (file)
  * are always placed at the very end. */
 static struct list_head flying_urbs;
 
+/* user callbacks for pollfd changes */
+static libusb_pollfd_added_cb fd_added_cb = NULL;
+static libusb_pollfd_removed_cb fd_removed_cb = NULL;
+
 void usbi_io_init()
 {
        list_init(&flying_urbs);
+       fd_added_cb = NULL;
+       fd_removed_cb = NULL;
 }
 
 static int calculate_timeout(struct libusb_urb_handle *urbh,
@@ -275,6 +281,7 @@ API_EXPORTED int libusb_urb_handle_cancel_sync(struct libusb_dev_handle *devh,
        return 0;
 }
 
+#include <stdio.h>
 int handle_transfer_completion(struct libusb_dev_handle *devh,
        struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status)
 {
@@ -285,6 +292,11 @@ int handle_transfer_completion(struct libusb_dev_handle *devh,
 
        if (urb->type == USB_URB_TYPE_CONTROL) {
                libusb_ctrl_cb_fn callback = urbh->callback;
+               int i;
+               printf("ctrl completed status %d\n", status);
+               for (i = 0; i < urbh->transferred + sizeof(struct libusb_ctrl_setup); i++)
+                       printf("%02x ", ((unsigned char *) urb->buffer)[i]);
+               printf("\n");
                if (callback)
                        callback(devh, urbh, status, urb->buffer,
                                urb->buffer + sizeof(struct libusb_ctrl_setup), urbh->transferred,
@@ -701,3 +713,24 @@ API_EXPORTED void libusb_urb_handle_free(struct libusb_urb_handle *urbh)
        free(urbh);
 }
 
+API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
+       libusb_pollfd_removed_cb removed_cb)
+{
+       fd_added_cb = added_cb;
+       fd_removed_cb = removed_cb;
+}
+
+void usbi_add_pollfd(int fd, short events)
+{
+       usbi_dbg("add fd %d events %d", fd, events);
+       if (fd_added_cb)
+               fd_added_cb(fd, events);
+}
+
+void usbi_remove_pollfd(int fd)
+{
+       usbi_dbg("remove fd %d", fd);
+       if (fd_removed_cb)
+               fd_removed_cb(fd);
+}
+
index b07314e..6cfc780 100644 (file)
@@ -236,11 +236,6 @@ int libusb_release_interface(libusb_dev_handle *dev, int iface);
 
 /* async I/O */
 
-struct libusb_pollfd {
-       int fd;
-       short events;
-};
-
 libusb_urb_handle *libusb_async_control_transfer(libusb_dev_handle *devh,
        struct libusb_control_transfer *transfer, libusb_ctrl_cb_fn callback,
        void *user_data, unsigned int timeout);
@@ -256,11 +251,6 @@ int libusb_urb_handle_cancel_sync(libusb_dev_handle *devh,
        libusb_urb_handle *urbh);
 void libusb_urb_handle_free(libusb_urb_handle *urbh);
 
-int libusb_poll_timeout(struct timeval *tv);
-int libusb_poll(void);
-int libusb_get_next_timeout(struct timeval *tv);
-size_t libusb_get_pollfds(struct libusb_pollfd **pollfds);
-
 /* sync I/O */
 
 int libusb_control_transfer(libusb_dev_handle *devh,
@@ -272,6 +262,22 @@ int libusb_interrupt_transfer(libusb_dev_handle *devh,
        struct libusb_bulk_transfer *transfer, int *transferred,
        unsigned int timeout);
 
+/* polling and timeouts */
+struct libusb_pollfd {
+       int fd;
+       short events;
+};
+
+int libusb_poll_timeout(struct timeval *tv);
+int libusb_poll(void);
+int libusb_get_next_timeout(struct timeval *tv);
+size_t libusb_get_pollfds(struct libusb_pollfd **pollfds);
+
+typedef void (*libusb_pollfd_added_cb)(int fd, short events);
+typedef void (*libusb_pollfd_removed_cb)(int fd);
+void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
+       libusb_pollfd_removed_cb removed_cb);
+
 #ifdef __cplusplus
 }
 #endif
index 127990f..b639ed6 100644 (file)
@@ -193,6 +193,8 @@ struct usb_descriptor_header {
 extern struct list_head open_devs;
 
 void usbi_io_init(void);
+void usbi_add_pollfd(int fd, short events);
+void usbi_remove_pollfd(int fd);
 
 int usbi_parse_descriptor(unsigned char *source, char *descriptor, void *dest);
 int usbi_parse_configuration(struct libusb_config_descriptor *config,