diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-02-26 22:11:34 +0000 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-02-26 22:39:28 +0000 |
commit | b873521a6f575628d535f89278bb67888004d0ca (patch) | |
tree | c76261ffdd9c2f6e43bf847dc90fdbfb85a8e286 | |
parent | ca66e16a370c828d08a5bc3f9f203db145c81a4c (diff) | |
download | libusb-b873521a6f575628d535f89278bb67888004d0ca.tar.gz |
Notifications for changes to the fd set
Applications can now be notified when they should start and stop polling
new file descriptors.
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | libusb/core.c | 6 | ||||
-rw-r--r-- | libusb/io.c | 33 | ||||
-rw-r--r-- | libusb/libusb.h | 26 | ||||
-rw-r--r-- | libusb/libusbi.h | 2 |
5 files changed, 57 insertions, 11 deletions
@@ -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? diff --git a/libusb/core.c b/libusb/core.c index e9939f4..1560567 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -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) { diff --git a/libusb/io.c b/libusb/io.c index ae572ab..07a7bf0 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -38,9 +38,15 @@ * 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); +} + diff --git a/libusb/libusb.h b/libusb/libusb.h index b07314e..6cfc780 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -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 diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 127990f..b639ed6 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -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, |