Date: Sat, 30 May 2009 11:28:16 GMT From: Sylvestre Gallon <syl@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 163077 for review Message-ID: <200905301128.n4UBSGad022347@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163077 Change 163077 by syl@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905301128.n4UBSGad022347>