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:
parent
2defc4116b
commit
4b9e253213
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
100
src/usb.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue