From owner-p4-projects@FreeBSD.ORG Mon May 11 08:45:25 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B74EA106566C; Mon, 11 May 2009 08:45:24 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77517106564A for ; Mon, 11 May 2009 08:45:24 +0000 (UTC) (envelope-from syl@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 64EEB8FC0C for ; Mon, 11 May 2009 08:45:24 +0000 (UTC) (envelope-from syl@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4B8jOTB028998 for ; Mon, 11 May 2009 08:45:24 GMT (envelope-from syl@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4B8jOQu028996 for perforce@freebsd.org; Mon, 11 May 2009 08:45:24 GMT (envelope-from syl@FreeBSD.org) Date: Mon, 11 May 2009 08:45:24 GMT Message-Id: <200905110845.n4B8jOQu028996@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to syl@FreeBSD.org using -f From: Sylvestre Gallon To: Perforce Change Reviews Cc: Subject: PERFORCE change 161928 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 May 2009 08:45:25 -0000 http://perforce.freebsd.org/chv.cgi?CH=161928 Change 161928 by syl@syl_atuin on 2009/05/11 08:44:31 - Add a missing field in struct libusb_context. - Implement list foreach - Add default_context handling in libusb_init. - Init I/O mutex in libusb_init. - Add pollfds handling in libusb_init. - Implent libusb_get_pollfds. Affected files ... .. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#8 edit .. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#9 edit Differences ... ==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#8 (text+ko) ==== @@ -196,6 +196,9 @@ struct list_head flying_transfers; pthread_mutex_t flying_transfers_lock; + struct list_head pollfds; + pthread_mutex_t pollfds_lock; + unsigned int pollfd_modify; pthread_mutex_t pollfd_modify_lock; ==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#9 (text+ko) ==== @@ -25,7 +25,9 @@ #include #include +#include #include +#include #include #include "libusb20.h" @@ -34,6 +36,13 @@ #include "libusb.h" /* + * XXX TODO + * - default context handling. + * - implement debug messages. + * - implement last io funcs. + */ + +/* * The two following macros were taken from the original LibUSB v1.0 * for sake of compatibility: */ @@ -54,6 +63,18 @@ (entry)->next->prev = (entry)->prev; \ (entry)->prev->next = (entry)->next; +#define LIST_ENT(ptr, type, member) \ + ((type *)((char *)(ptr) - (unsigned long) (&((type*)0L)->member))) +#define LIST_FOREACH_ENTRY(pos, head, member) \ + for (pos = LIST_ENT((head)->next, typeof(*pos), member) ; \ + &pos->member != head ; \ + pos = LIST_ENT(pos->member.next, typeof(*pos), member)) +#define LIST_FOREACH_ENTRY_SAFE(pos, n, head, member) \ + for (pos = LIST_ENT((head)->next, typeof(*pos), member), \ + n = LIST_ENT(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = LIST_ENT(n->member.next, typeof(*n), member)) + /* fetxh libusb20_transfer from libusb20_device */ #define GET_XFER(xfer, endpoint, pdev)\ xfer = libusb20_tr_get_pointer(pdev, \ @@ -61,8 +82,16 @@ if (xfer == NULL) \ return (LIBUSB_ERROR_OTHER); +struct libusb_context *usbi_default_context = NULL; +static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; + /* Library initialisation / deinitialisation */ +struct usb_pollfd { + struct libusb_pollfd pollfd; + struct list_head list; +}; + void libusb_set_debug(libusb_context * ctx, int level) { @@ -70,10 +99,64 @@ 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 ** contex) { struct libusb_context *ctx; + int ret; ctx = malloc(sizeof(*ctx)); if (!ctx) @@ -86,6 +169,39 @@ USB_LIST_INIT(&ctx->usb_devs); USB_LIST_INIT(&ctx->open_devs); + pthread_mutex_init(&ctx->flying_transfers_lock, NULL); + pthread_mutex_init(&ctx->pollfds_lock, NULL); + pthread_mutex_init(&ctx->pollfd_modify_lock, NULL); + pthread_mutex_init(&ctx->events_lock, NULL); + pthread_mutex_init(&ctx->event_waiters_lock, NULL); + pthread_cond_init(&ctx->event_waiters_cond, NULL); + + USB_LIST_INIT(&ctx->flying_transfers); + USB_LIST_INIT(&ctx->pollfds); + + ret = pipe(ctx->ctrl_pipe); + if (ret < 0) { + free(ctx); + usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); + close(ctx->ctrl_pipe[0]); + close(ctx->ctrl_pipe[1]); + return (LIBUSB_ERROR_OTHER); + } + + ret = usb_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN); + if (ret < 0) { + free(ctx); + usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); + close(ctx->ctrl_pipe[0]); + close(ctx->ctrl_pipe[1]); + return ret; + } + + pthread_mutex_lock(&default_context_lock); + if (!usbi_default_context) { + usbi_default_context = ctx; + } + if (contex) *contex = ctx; @@ -747,7 +863,27 @@ struct libusb_pollfd ** libusb_get_pollfds(libusb_context * ctx) { - return (NULL); + struct usb_pollfd *pollfd; + libusb_pollfd **ret; + int i; + + i = 0; + pthread_mutex_lock(&ctx->pollfds_lock); + LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) + i++; + + ret = calloc(i + 1 , sizeof(struct libusb_pollfd *)); + if (ret == NULL) { + pthread_mutex_unlock(&ctx->pollfds_lock); + return (NULL); + } + + i = 0; + LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) + ret[i++] = (struct libusb_pollfd *) pollfd; + ret[i] = NULL; + + return (ret); } /* Synchronous device I/O */