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; 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_PRIV int usb_source_add(struct sr_context *ctx, int timeout,
sr_receive_data_callback_t cb, void *cb_data) sr_receive_data_callback_t cb, void *cb_data)
{ {
#ifdef _WIN32 #ifdef _WIN32
sr_err("Operation not supported on Windows yet."); ctx->usb_event = CreateEvent(NULL, TRUE, FALSE, NULL);
return SR_ERR; 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 #else
const struct libusb_pollfd **lupfd; const struct libusb_pollfd **lupfd;
unsigned int i; 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++) for (i = 0; lupfd[i]; i++)
sr_source_add(lupfd[i]->fd, lupfd[i]->events, timeout, cb, cb_data); sr_source_add(lupfd[i]->fd, lupfd[i]->events, timeout, cb, cb_data);
free(lupfd); free(lupfd);
#endif
return SR_OK; return SR_OK;
#endif
} }
SR_PRIV int usb_source_remove(struct sr_context *ctx) SR_PRIV int usb_source_remove(struct sr_context *ctx)
{ {
#ifdef _WIN32 #ifdef _WIN32
sr_err("Operation not supported on Windows yet."); ctx->usb_thread_running = FALSE;
return SR_ERR; 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 #else
const struct libusb_pollfd **lupfd; const struct libusb_pollfd **lupfd;
unsigned int i; unsigned int i;
@ -276,7 +317,7 @@ SR_PRIV int usb_source_remove(struct sr_context *ctx)
for (i = 0; lupfd[i]; i++) for (i = 0; lupfd[i]; i++)
sr_source_remove(lupfd[i]->fd); sr_source_remove(lupfd[i]->fd);
free(lupfd); free(lupfd);
#endif
return SR_OK; return SR_OK;
#endif
} }

View File

@ -60,6 +60,15 @@
struct sr_context { struct sr_context {
#ifdef HAVE_LIBUSB_1_0 #ifdef HAVE_LIBUSB_1_0
libusb_context *libusb_ctx; 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 #endif
}; };