USB: Remove Windows-specific event handling code

For the generic code to work on Windows, a version of libusb
with the experimental event-abstraction changes is required.
This commit is contained in:
Daniel Elstner 2015-09-04 23:47:08 +02:00
parent 2defc4116b
commit 4b9e253213
3 changed files with 13 additions and 99 deletions

View File

@ -206,12 +206,6 @@ struct sr_context {
#ifdef HAVE_LIBUSB_1_0 #ifdef HAVE_LIBUSB_1_0
libusb_context *libusb_ctx; libusb_context *libusb_ctx;
gboolean usb_source_present; gboolean usb_source_present;
# ifdef G_OS_WIN32
int64_t usb_timeout;
int64_t usb_due;
sr_receive_data_callback usb_cb;
void *usb_cb_data;
# endif
#endif #endif
}; };

View File

@ -409,7 +409,7 @@ static int sr_session_iteration(struct sr_session *session)
struct source *source; struct source *source;
GPollFD *pollfd; GPollFD *pollfd;
gintptr poll_object; gintptr poll_object;
#if HAVE_LIBUSB_1_0 && !defined(G_OS_WIN32) #if HAVE_LIBUSB_1_0
int64_t usb_timeout; int64_t usb_timeout;
int64_t usb_due; int64_t usb_due;
struct timeval tv; struct timeval tv;
@ -427,7 +427,7 @@ static int sr_session_iteration(struct sr_session *session)
min_due = source->due; min_due = source->due;
source->triggered = FALSE; source->triggered = FALSE;
} }
#if HAVE_LIBUSB_1_0 && !defined(G_OS_WIN32) #if HAVE_LIBUSB_1_0
usb_due = INT64_MAX; usb_due = INT64_MAX;
if (session->ctx->usb_source_present) { if (session->ctx->usb_source_present) {
ret = libusb_get_next_timeout(session->ctx->libusb_ctx, &tv); ret = libusb_get_next_timeout(session->ctx->libusb_ctx, &tv);
@ -506,7 +506,7 @@ static int sr_session_iteration(struct sr_session *session)
revents = 0; revents = 0;
due = source->due; due = source->due;
#if HAVE_LIBUSB_1_0 && !defined(G_OS_WIN32) #if HAVE_LIBUSB_1_0
if (usb_due < due && poll_object if (usb_due < due && poll_object
== (gintptr)session->ctx->libusb_ctx) == (gintptr)session->ctx->libusb_ctx)
due = usb_due; due = usb_due;

100
src/usb.c
View File

@ -184,104 +184,19 @@ SR_PRIV void sr_usb_close(struct sr_usb_dev_inst *usb)
sr_dbg("Closed USB device %d.%d.", usb->bus, usb->address); sr_dbg("Closed USB device %d.%d.", usb->bus, usb->address);
} }
#ifdef G_OS_WIN32
/*
* USB callback wrapper run when the main loop is idle.
*/
static int usb_callback(int fd, int revents, void *cb_data)
{
int64_t start_time, stop_time, due, timeout;
struct timeval tv;
struct sr_context *ctx;
int ret;
(void)fd;
(void)revents;
ctx = cb_data;
start_time = g_get_monotonic_time();
due = ctx->usb_due;
if (due > start_time) {
timeout = due - start_time;
tv.tv_sec = timeout / G_USEC_PER_SEC;
tv.tv_usec = timeout % G_USEC_PER_SEC;
sr_spew("libusb_handle_events enter: %g ms timeout",
1e-3 * timeout);
ret = libusb_handle_events_timeout_completed(ctx->libusb_ctx,
(ctx->usb_timeout < 0) ? NULL : &tv, NULL);
if (ret != 0) {
/* Warn but still invoke the callback, to give
* the driver a chance to deal with the problem.
*/
sr_warn("Error handling libusb event (%s)",
libusb_error_name(ret));
}
stop_time = g_get_monotonic_time();
sr_spew("libusb_handle_events leave: %g ms elapsed",
1e-3 * (stop_time - start_time));
/*
* The event source may have been removed by the driver's
* libusb transfer callback. Skip the callback in that case.
*/
if (!ctx->usb_source_present)
return TRUE;
} else {
/* Timeout already expired on entry.
*/
stop_time = start_time;
sr_spew("libusb_handle_events skipped");
}
if (ctx->usb_timeout >= 0)
ctx->usb_due = stop_time + ctx->usb_timeout;
/*
* Run the registered callback to execute any follow-up activity
* to libusb's event handling.
*/
return ctx->usb_cb(-1, (stop_time < due) ? G_IO_IN : 0,
ctx->usb_cb_data);
}
#endif
SR_PRIV int usb_source_add(struct sr_session *session, struct sr_context *ctx, SR_PRIV int usb_source_add(struct sr_session *session, struct sr_context *ctx,
int timeout, sr_receive_data_callback cb, void *cb_data) int timeout, sr_receive_data_callback cb, void *cb_data)
{ {
const struct libusb_pollfd **lupfd;
GPollFD *pollfds;
int i;
int num_fds = 0;
int ret; int ret;
if (ctx->usb_source_present) { if (ctx->usb_source_present) {
sr_err("A USB event source is already present."); sr_err("A USB event source is already present.");
return SR_ERR; return SR_ERR;
} }
#ifdef G_OS_WIN32
if (timeout >= 0) {
ctx->usb_timeout = INT64_C(1000) * timeout;
ctx->usb_due = g_get_monotonic_time() + ctx->usb_timeout;
} else {
ctx->usb_timeout = -1;
ctx->usb_due = INT64_MAX;
}
ctx->usb_cb = cb;
ctx->usb_cb_data = cb_data;
/*
* TODO: Install an idle source which will fire permanently, and block
* in a wrapper callback until any libusb events have been processed.
* This will have to do for now, until we implement a proper way to
* deal with libusb events on Windows.
*/
ret = sr_session_source_add_internal(session, NULL, 0,
0, &usb_callback, ctx, (gintptr)ctx->libusb_ctx);
#else
const struct libusb_pollfd **lupfd;
GPollFD *pollfds;
int i;
int num_fds = 0;
lupfd = libusb_get_pollfds(ctx->libusb_ctx); lupfd = libusb_get_pollfds(ctx->libusb_ctx);
if (!lupfd || !lupfd[0]) { if (!lupfd || !lupfd[0]) {
free(lupfd); free(lupfd);
@ -293,7 +208,12 @@ SR_PRIV int usb_source_add(struct sr_session *session, struct sr_context *ctx,
pollfds = g_new(GPollFD, num_fds); pollfds = g_new(GPollFD, num_fds);
for (i = 0; i < num_fds; ++i) { for (i = 0; i < num_fds; ++i) {
#if defined(G_OS_WIN32) && (GLIB_SIZEOF_VOID_P == 4)
/* Avoid a warning on 32-bit Windows. */
pollfds[i].fd = (gintptr)lupfd[i]->fd;
#else
pollfds[i].fd = lupfd[i]->fd; pollfds[i].fd = lupfd[i]->fd;
#endif
pollfds[i].events = lupfd[i]->events; pollfds[i].events = lupfd[i]->events;
pollfds[i].revents = 0; pollfds[i].revents = 0;
} }
@ -301,7 +221,7 @@ SR_PRIV int usb_source_add(struct sr_session *session, struct sr_context *ctx,
ret = sr_session_source_add_internal(session, pollfds, num_fds, ret = sr_session_source_add_internal(session, pollfds, num_fds,
timeout, cb, cb_data, (gintptr)ctx->libusb_ctx); timeout, cb, cb_data, (gintptr)ctx->libusb_ctx);
g_free(pollfds); g_free(pollfds);
#endif
ctx->usb_source_present = (ret == SR_OK); ctx->usb_source_present = (ret == SR_OK);
return ret; return ret;