[Spice-devel] [PATCH spice-gtk 05/10] usbredir: Create USB event source on demand
Hans de Goede
hdegoede at redhat.com
Mon Dec 19 03:24:38 PST 2011
This is a preparation patch for handling usb packet completion in a
separate thread.
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
gtk/Makefile.am | 1 +
gtk/channel-usbredir.c | 15 ++++++++++++
gtk/usb-device-manager-priv.h | 36 +++++++++++++++++++++++++++++
gtk/usb-device-manager.c | 50 +++++++++++++++++++++++++++++++---------
4 files changed, 90 insertions(+), 12 deletions(-)
create mode 100644 gtk/usb-device-manager-priv.h
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index b780882..9f208cc 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -236,6 +236,7 @@ libspice_client_glib_2_0_la_SOURCES = \
smartcard-manager.c \
smartcard-manager-priv.h \
usb-device-manager.c \
+ usb-device-manager-priv.h \
$(GUSB_SRCS) \
$(USB_ACL_HELPER_SRCS) \
\
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 58a4c21..26821c6 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -30,6 +30,7 @@
#include "usb-acl-helper.h"
#endif
#include "channel-usbredir-priv.h"
+#include "usb-device-manager-priv.h"
#endif
#include "spice-client.h"
@@ -197,6 +198,16 @@ static gboolean spice_usbredir_channel_open_device(
return FALSE;
}
+ if (!spice_usb_device_manager_start_event_listening(
+ spice_usb_device_manager_get(
+ spice_channel_get_session(SPICE_CHANNEL(channel)),
+ NULL, NULL),
+ err)) {
+ usbredirhost_close(priv->host);
+ priv->host = NULL;
+ return FALSE;
+ }
+
spice_channel_connect(SPICE_CHANNEL(channel));
priv->state = STATE_CONNECTING;
@@ -335,6 +346,10 @@ void spice_usbredir_channel_disconnect(SpiceUsbredirChannel *channel)
case STATE_CONNECTING:
case STATE_CONNECTED:
spice_channel_disconnect(SPICE_CHANNEL(channel), SPICE_CHANNEL_NONE);
+ spice_usb_device_manager_stop_event_listening(
+ spice_usb_device_manager_get(
+ spice_channel_get_session(SPICE_CHANNEL(channel)),
+ NULL, NULL));
/* This also closes the libusb handle we passed to its _open */
usbredirhost_close(priv->host);
priv->host = NULL;
diff --git a/gtk/usb-device-manager-priv.h b/gtk/usb-device-manager-priv.h
new file mode 100644
index 0000000..841c725
--- /dev/null
+++ b/gtk/usb-device-manager-priv.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede at redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USB_DEVICE_MANAGER_PRIV_H__
+#define __SPICE_USB_DEVICE_MANAGER_PRIV_H__
+
+#include "usb-device-manager.h"
+
+G_BEGIN_DECLS
+
+gboolean spice_usb_device_manager_start_event_listening(
+ SpiceUsbDeviceManager *manager, GError **err);
+
+void spice_usb_device_manager_stop_event_listening(
+ SpiceUsbDeviceManager *manager);
+
+G_END_DECLS
+
+#endif /* __SPICE_USB_DEVICE_MANAGER_PRIV_H__ */
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index fcd1685..6fba6f6 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -34,6 +34,7 @@
#include "spice-session-priv.h"
#include "spice-client.h"
#include "spice-marshal.h"
+#include "usb-device-manager-priv.h"
/**
* SECTION:usb-device-manager
@@ -91,6 +92,7 @@ struct _SpiceUsbDeviceManagerPrivate {
GUsbContext *context;
GUsbDeviceList *devlist;
GUsbSource *source;
+ int event_listeners;
#endif
GPtrArray *devices;
GPtrArray *channels;
@@ -202,8 +204,6 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
SpiceUsbDeviceManagerPrivate *priv = self->priv;
#ifdef USE_USBREDIR
- if (priv->source)
- g_usb_source_destroy(priv->source);
if (priv->devlist) {
g_object_unref(priv->devlist);
g_object_unref(priv->context);
@@ -476,10 +476,45 @@ static void spice_usb_device_manager_channel_connect_cb(
g_simple_async_result_complete(result);
g_object_unref(result);
}
-#endif
/* ------------------------------------------------------------------ */
/* private api */
+
+gboolean spice_usb_device_manager_start_event_listening(
+ SpiceUsbDeviceManager *self, GError **err)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ priv->event_listeners++;
+ 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;
+}
+
+void spice_usb_device_manager_stop_event_listening(
+ SpiceUsbDeviceManager *self)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ 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;
+}
+#endif
+
static SpiceUsbredirChannel *spice_usb_device_manager_get_channel_for_dev(
SpiceUsbDeviceManager *manager, SpiceUsbDevice *_device)
{
@@ -603,7 +638,6 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
#ifdef USE_USBREDIR
SpiceUsbDeviceManagerPrivate *priv = self->priv;
- GError *e = NULL;
guint i;
if (spice_usb_device_manager_is_device_connected(self, device)) {
@@ -613,14 +647,6 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
goto done;
}
- if (!priv->source) {
- priv->source = g_usb_source_new(priv->main_context, priv->context, &e);
- if (e) {
- g_simple_async_result_take_error(result, e);
- goto done;
- }
- }
-
for (i = 0; i < priv->channels->len; i++) {
SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
--
1.7.7.4
More information about the Spice-devel
mailing list