Implement usb_source_add and usb_source_remove for Windows.

This commit is contained in:
Martin Ling 2013-12-22 07:16:56 +00:00
parent 6c60facc19
commit 5321ac6b52
2 changed files with 56 additions and 6 deletions

View File

@ -244,12 +244,49 @@ SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb)
return ret;
}
#ifdef _WIN32
SR_PRIV gpointer usb_thread(gpointer data)
{
struct sr_context *ctx = data;
while (ctx->usb_thread_running) {
g_mutex_lock(&ctx->usb_mutex);
libusb_wait_for_event(ctx->libusb_ctx, NULL);
SetEvent(ctx->usb_event);
g_mutex_unlock(&ctx->usb_mutex);
g_thread_yield();
}
return NULL;
}
SR_PRIV int usb_callback(int fd, int revents, void *cb_data)
{
struct sr_context *ctx = cb_data;
int ret;
g_mutex_lock(&ctx->usb_mutex);
ret = ctx->usb_cb(fd, revents, ctx->usb_cb_data);
ResetEvent(ctx->usb_event);
g_mutex_unlock(&ctx->usb_mutex);
return ret;
}
#endif
SR_PRIV int usb_source_add(struct sr_context *ctx, int timeout,
sr_receive_data_callback_t cb, void *cb_data)
{
#ifdef _WIN32
sr_err("Operation not supported on Windows yet.");
return SR_ERR;
ctx->usb_event = CreateEvent(NULL, TRUE, FALSE, NULL);
g_mutex_init(&ctx->usb_mutex);
ctx->usb_thread_running = TRUE;
ctx->usb_thread = g_thread_new("usb", usb_thread, ctx);
ctx->usb_pollfd.fd = ctx->usb_event;
ctx->usb_pollfd.events = G_IO_IN;
ctx->usb_cb = cb;
ctx->usb_cb_data = cb_data;
sr_session_source_add_pollfd(&ctx->usb_pollfd, timeout, usb_callback, ctx);
#else
const struct libusb_pollfd **lupfd;
unsigned int i;
@ -258,16 +295,20 @@ SR_PRIV int usb_source_add(struct sr_context *ctx, int timeout,
for (i = 0; lupfd[i]; i++)
sr_source_add(lupfd[i]->fd, lupfd[i]->events, timeout, cb, cb_data);
free(lupfd);
#endif
return SR_OK;
#endif
}
SR_PRIV int usb_source_remove(struct sr_context *ctx)
{
#ifdef _WIN32
sr_err("Operation not supported on Windows yet.");
return SR_ERR;
ctx->usb_thread_running = FALSE;
libusb_unlock_events(ctx->libusb_ctx);
g_thread_join(ctx->usb_thread);
g_mutex_clear(&ctx->usb_mutex);
sr_session_source_remove_pollfd(&ctx->usb_pollfd);
CloseHandle(ctx->usb_event);
#else
const struct libusb_pollfd **lupfd;
unsigned int i;
@ -276,7 +317,7 @@ SR_PRIV int usb_source_remove(struct sr_context *ctx)
for (i = 0; lupfd[i]; i++)
sr_source_remove(lupfd[i]->fd);
free(lupfd);
#endif
return SR_OK;
#endif
}

View File

@ -60,6 +60,15 @@
struct sr_context {
#ifdef HAVE_LIBUSB_1_0
libusb_context *libusb_ctx;
#ifdef _WIN32
GThread *usb_thread;
gboolean usb_thread_running;
GMutex usb_mutex;
HANDLE usb_event;
GPollFD usb_pollfd;
sr_receive_data_callback_t usb_cb;
void *usb_cb_data;
#endif
#endif
};