On Mon, Dec 19, 2011 at 12:24:40PM +0100, Hans de Goede wrote: > This solves various latency issues with USB handling. > > Signed-off-by: Hans de Goede <hdego...@redhat.com> > --- > gtk/channel-usbredir.c | 5 +++++ > gtk/usb-device-manager.c | 45 ++++++++++++++++++++++++++++++++------------- > 2 files changed, 37 insertions(+), 13 deletions(-) > > diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c > index dfd1655..e14088a 100644 > --- a/gtk/channel-usbredir.c > +++ b/gtk/channel-usbredir.c > @@ -352,6 +352,11 @@ void > spice_usbredir_channel_disconnect(SpiceUsbredirChannel *channel) > case STATE_CONNECTING: > case STATE_CONNECTED: > spice_channel_disconnect(SPICE_CHANNEL(channel), SPICE_CHANNEL_NONE); > + /* > + * This sets the usb event thread run condition to FALSE, therefor > + * it must be done before usbredirhost_close, as usbredirhost_close > + * will interrupt the libusb_handle_events call in the thread. > + */ > spice_usb_device_manager_stop_event_listening( > spice_usb_device_manager_get( > spice_channel_get_session(SPICE_CHANNEL(channel)), > diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c > index 6fba6f6..44ed84d 100644 > --- a/gtk/usb-device-manager.c > +++ b/gtk/usb-device-manager.c > @@ -26,8 +26,8 @@ > #include "glib-compat.h" > > #ifdef USE_USBREDIR > -#include <gusb/gusb-source.h> > #include <gusb/gusb-device-list.h> > +#include <gusb/gusb-context-private.h> > #include "channel-usbredir-priv.h" > #endif > > @@ -91,8 +91,9 @@ struct _SpiceUsbDeviceManagerPrivate { > #ifdef USE_USBREDIR > GUsbContext *context; > GUsbDeviceList *devlist; > - GUsbSource *source; > int event_listeners; > + GThread *event_thread; > + gboolean event_thread_run; > #endif > GPtrArray *devices; > GPtrArray *channels; > @@ -204,6 +205,9 @@ static void spice_usb_device_manager_finalize(GObject > *gobject) > SpiceUsbDeviceManagerPrivate *priv = self->priv; > > #ifdef USE_USBREDIR > + if (priv->event_thread) > + g_thread_join(priv->event_thread); > + > if (priv->devlist) { > g_object_unref(priv->devlist); > g_object_unref(priv->context); > @@ -480,6 +484,18 @@ static void spice_usb_device_manager_channel_connect_cb( > /* ------------------------------------------------------------------ */ > /* private api */ > > +static gpointer spice_usb_device_magager_usb_ev_thread(gpointer user_data)
s/magager/manager > +{ > + SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data); > + SpiceUsbDeviceManagerPrivate *priv = self->priv; > + > + while (priv->event_thread_run) { > + libusb_handle_events(_g_usb_context_get_context(priv->context)); > + } Maybe we should log something when libusb_handle_events returns LIBUSB_ERROR_* ? > + > + return NULL; > +} > + > gboolean spice_usb_device_manager_start_event_listening( > SpiceUsbDeviceManager *self, GError **err) > { > @@ -491,10 +507,18 @@ gboolean spice_usb_device_manager_start_event_listening( > if (priv->event_listeners > 1) > return TRUE; > > - g_return_val_if_fail(priv->source == NULL, FALSE); > - > - priv->source = g_usb_source_new(priv->main_context, priv->context, err); > - return priv->source != NULL; > + /* We don't join the thread when we stop event listening, as the > + libusb_handle_events call in the thread won't exit until the > + libusb_close call for the device is made from usbredirhost_close. */ > + if (priv->event_thread) { > + g_thread_join(priv->event_thread); > + priv->event_thread = NULL; > + } > + priv->event_thread_run = TRUE; > + priv->event_thread = g_thread_create( > + spice_usb_device_magager_usb_ev_thread, > + self, TRUE, err); Do we need to join threads at all? Not needing to call g_thread_join would make the code simpler. Ie the 3rd arg could be FALSE here. Christophe > + return priv->event_thread != NULL; > } > > void spice_usb_device_manager_stop_event_listening( > @@ -505,13 +529,8 @@ void spice_usb_device_manager_stop_event_listening( > g_return_if_fail(priv->event_listeners > 0); > > priv->event_listeners--; > - if (priv->event_listeners != 0) > - return; > - > - g_return_if_fail(priv->source != NULL); > - > - g_usb_source_destroy(priv->source); > - priv->source = NULL; > + if (priv->event_listeners == 0) > + priv->event_thread_run = FALSE; > } > #endif > > -- > 1.7.7.4 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/spice-devel
pgpNg6zktLA46.pgp
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel