PERFORCE change 163077 for review
Sylvestre Gallon
syl at FreeBSD.org
Sat May 30 11:28:18 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163077
Change 163077 by syl at syl_rincewind on 2009/05/30 11:28:06
- Remove ; at the end of a if in handle_timeouts.
- Finish the implementation of handle_events.
- Implement the usb_handle_disconnect helper.
- Implement the usb_handle_transfer_completion helper.
- Inline usb_add_pollfd and usb_remove_pollfd into libusb10.h.
Affected files ...
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#20 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.h#3 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_io.c#4 edit
Differences ...
==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#20 (text+ko) ====
@@ -57,59 +57,6 @@
ctx->debug = level;
}
-static int
-usb_add_pollfd(libusb_context *ctx, int fd, short events)
-{
- struct usb_pollfd *pollfd;
-
- if (ctx == NULL)
- return (LIBUSB_ERROR_INVALID_PARAM);
-
- pollfd = malloc(sizeof(*pollfd));
- if (pollfd == NULL)
- return (LIBUSB_ERROR_NO_MEM);
-
- pollfd->pollfd.fd = fd;
- pollfd->pollfd.events = events;
-
- pthread_mutex_lock(&ctx->pollfds_lock);
- LIST_ADD_TAIL(&pollfd->list, &ctx->pollfds);
- pthread_mutex_unlock(&ctx->pollfds_lock);
-
- if (ctx->fd_added_cb)
- ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
- return (0);
-}
-
-static void
-usb_remove_pollfd(libusb_context *ctx, int fd)
-{
- struct usb_pollfd *pollfd;
- int found;
-
- found = 0;
- pthread_mutex_lock(&ctx->pollfds_lock);
-
- LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) {
- if (pollfd->pollfd.fd == fd) {
- found = 1;
- break ;
- }
- }
-
- if (found == 0) {
- pthread_mutex_unlock(&ctx->pollfds_lock);
- return ;
- }
-
- LIST_DEL(&pollfd->list);
- pthread_mutex_unlock(&ctx->pollfds_lock);
- free(pollfd);
-
- if (ctx->fd_removed_cb)
- ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
-}
-
int
libusb_init(libusb_context ** context)
{
==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.h#3 (text+ko) ====
@@ -95,4 +95,127 @@
uint8_t flags;
};
+static inline int
+usb_add_pollfd(libusb_context *ctx, int fd, short events)
+{
+ struct usb_pollfd *pollfd;
+
+ if (ctx == NULL)
+ return (LIBUSB_ERROR_INVALID_PARAM);
+
+ pollfd = malloc(sizeof(*pollfd));
+ if (pollfd == NULL)
+ return (LIBUSB_ERROR_NO_MEM);
+
+ pollfd->pollfd.fd = fd;
+ pollfd->pollfd.events = events;
+
+ pthread_mutex_lock(&ctx->pollfds_lock);
+ LIST_ADD_TAIL(&pollfd->list, &ctx->pollfds);
+ pthread_mutex_unlock(&ctx->pollfds_lock);
+
+ if (ctx->fd_added_cb)
+ ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
+ return (0);
+}
+
+static inline void
+usb_remove_pollfd(libusb_context *ctx, int fd)
+{
+ struct usb_pollfd *pollfd;
+ int found;
+
+ found = 0;
+ pthread_mutex_lock(&ctx->pollfds_lock);
+
+ LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) {
+ if (pollfd->pollfd.fd == fd) {
+ found = 1;
+ break ;
+ }
+ }
+
+ if (found == 0) {
+ pthread_mutex_unlock(&ctx->pollfds_lock);
+ return ;
+ }
+
+ LIST_DEL(&pollfd->list);
+ pthread_mutex_unlock(&ctx->pollfds_lock);
+ free(pollfd);
+
+ if (ctx->fd_removed_cb)
+ ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
+}
+
+static inline void
+usb_handle_transfer_completion(struct usb_transfer *uxfer,
+ enum libusb_transfer_status status)
+{
+ libusb_transfer *xfer;
+ libusb_context *ctx;
+ int len;
+
+ xfer = (struct libusb_transfer *) ((uint8_t *)uxfer +
+ sizeof(struct usb_transfer));
+ ctx = xfer->dev_handle->dev->ctx;
+
+ pthread_mutex_lock(&ctx->flying_transfers_lock);
+ LIST_DEL(&uxfer->list);
+ pthread_mutex_unlock(&ctx->flying_transfers_lock);
+
+ if (status == LIBUSB_TRANSFER_COMPLETED && xfer->flags &
+ LIBUSB_TRANSFER_SHORT_NOT_OK) {
+ len = xfer->length;
+ if (xfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
+ len -= sizeof(libusb_control_setup);
+ if (len != uxfer->transferred) {
+ status = LIBUSB_TRANSFER_ERROR;
+ }
+ }
+
+ xfer->status = status;
+ xfer->actual_length = uxfer->transferred;
+
+ if (xfer->callback)
+ xfer->callback(xfer);
+ if (xfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
+ libusb_free_transfer(xfer);
+
+ pthread_mutex_lock(&ctx->event_waiters_lock);
+ pthread_cond_broadcast(&ctx->event_waiters_cond);
+ pthread_mutex_unlock(&ctx->event_waiters_lock);
+}
+
+static inline void
+usb_handle_disconnect(struct libusb_device_handle *devh)
+{
+ struct libusb_context *ctx;
+ struct libusb_transfer *xfer;
+ struct usb_transfer *cur;
+ struct usb_transfer *to_cancel;
+
+ ctx = devh->dev->ctx;
+
+ while (1) {
+ pthread_mutex_lock(&ctx->flying_transfers_lock);
+ to_cancel = NULL;
+ LIST_FOREACH_ENTRY(cur, &ctx->flying_transfers, list) {
+ xfer = (struct libusb_transfer *) ((uint8_t *)cur +
+ sizeof(struct usb_transfer));
+ if (xfer->dev_handle == devh) {
+ to_cancel = cur;
+ break ;
+ }
+ }
+ pthread_mutex_unlock(&ctx->flying_transfers_lock);
+
+ if (to_cancel == NULL)
+ break ;
+
+ usb_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
+ }
+ return ;
+}
+
#endif /*__LIBUSB10_H__*/
==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_io.c#4 (text+ko) ====
@@ -74,7 +74,7 @@
ret = 0;
pthread_mutex_lock(&ctx->flying_transfers_lock);
- if (USB_LIST_EMPTY(&ctx->flying_transfers));
+ if (USB_LIST_EMPTY(&ctx->flying_transfers))
goto out;
ret = clock_gettime(CLOCK_MONOTONIC, &sys_ts);
@@ -94,7 +94,7 @@
goto out;
xfer->flags |= USB_TIMED_OUT;
- uxfer = (libusb_transfer *) (((uint8_t *)xfer) +
+ uxfer = (libusb_transfer *) ((uint8_t *)xfer +
sizeof(struct usb_transfer));
ret = libusb_cancel_transfer(uxfer);
}
@@ -106,13 +106,19 @@
static int
handle_events(struct libusb_context *ctx, struct timeval *tv)
{
+ struct libusb_pollfd *tmppollfd;
+ struct libusb_device_handle *devh;
struct usb_pollfd *ipollfd;
- struct libusb_pollfd *tmppollfd;
+ struct usb_transfer *cur;
+ struct usb_transfer *cancel;
+ struct libusb_transfer *xfer;
struct pollfd *fds;
+ struct pollfd *tfds;
+ nfds_t nfds;
int tmpfd;
+ int tmp;
int ret;
int timeout;
- nfds_t nfds;
int i;
nfds = 0;
@@ -163,7 +169,33 @@
}
}
- ret = /*unknown*/0;
+ pthread_mutex_lock(&ctx->open_devs_lock);
+ for (i = 0 ; i < nfds && ret > 0 ; i++) {
+ tfds = &fds[i];
+
+ if (!tfds->revents)
+ continue;
+
+ ret--;
+ LIST_FOREACH_ENTRY(devh, &ctx->open_devs, list) {
+ if (libusb20_dev_get_fd(devh->os_priv) == tfds->fd)
+ break ;
+ }
+
+ if (tfds->revents & POLLERR) {
+ usb_remove_pollfd(ctx, libusb20_dev_get_fd(devh->os_priv));
+ usb_handle_disconnect(devh);
+ continue ;
+ }
+ ret = libusb20_dev_process(devh->os_priv);
+ if (ret == 0 || LIBUSB20_ERROR_NO_DEVICE)
+ continue;
+ else if (ret < 0)
+ goto out;
+ }
+out:
+ pthread_mutex_unlock(&ctx->open_devs_lock);
+
handled:
free(fds);
return ret;
More information about the p4-projects
mailing list