PERFORCE change 161928 for review

Sylvestre Gallon syl at FreeBSD.org
Mon May 11 08:45:25 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=161928

Change 161928 by syl at 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 <sys/queue.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <stdio.h>
+#include <poll.h>
 #include <pthread.h>
 
 #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 */


More information about the p4-projects mailing list