[Spice-commits] 22 commits - doc/reference gtk/channel-display.c gtk/channel-main.c gtk/channel-smartcard.c gtk/channel-webdav.c gtk/desktop-integration.c gtk/map-file gtk/spice-audio.c gtk/spice-channel.c gtk/spice-channel.h gtk/spice-glib-sym-file gtk/spice-gtk-session.c gtk/spice-session.c gtk/spice-session.h gtk/spice-session-priv.h gtk/usb-device-manager.c
Marc-André Lureau
elmarco at kemper.freedesktop.org
Mon Dec 1 08:31:51 PST 2014
doc/reference/spice-gtk-sections.txt | 1
gtk/channel-display.c | 5
gtk/channel-main.c | 12
gtk/channel-smartcard.c | 19 -
gtk/channel-webdav.c | 34 --
gtk/desktop-integration.c | 7
gtk/map-file | 1
gtk/spice-audio.c | 50 ---
gtk/spice-channel.c | 15 -
gtk/spice-channel.h | 3
gtk/spice-glib-sym-file | 1
gtk/spice-gtk-session.c | 4
gtk/spice-session-priv.h | 98 -------
gtk/spice-session.c | 488 ++++++++++++++++++++++++++++-------
gtk/spice-session.h | 1
gtk/usb-device-manager.c | 64 +---
16 files changed, 484 insertions(+), 319 deletions(-)
New commits:
commit 14dc8e170e71e4b860afe84cd20900b462e9b132
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 17:31:43 2014 +0100
usb: keep USB context alive as long as channels exist
It was assumed the session would remain alive as long as channel
existed, so USB context would be valid too. Now that channels
are removed from session, USB context may be destroyed before
channels. This produces invalid read/write on USB context.
Make sure the context is alive as long as USB channels are by
adding a reference on USB manager.
==6939== Invalid write of size 4
==6939== at 0x394B604482: libusb_set_debug (core.c:1850)
==6939== by 0x3953A063D5: usbredirhost_open_full (usbredirhost.c:741)
==6939== by 0x4EC7E2F:
spice_usbredir_channel_set_context (channel-usbredir.c:212)
==6939== by 0x4EC7AB6:
spice_usbredir_channel_reset (channel-usbredir.c:125)
==6939== by 0x4EACCDC: spice_channel_reset (spice-channel.c:2621)
==6939== by 0x4EACDB4: channel_disconnect (spice-channel.c:2640)
==6939== by 0x4EAC28F: spice_channel_coroutine (spice-channel.c:2423)
==6939== by 0x4EE8B1C: coroutine_trampoline (coroutine_ucontext.c:63)
==6939== by 0x4EE87D6: continuation_trampoline (continuation.c:55)
==6939== by 0x3928247FEF: ??? (in /usr/lib64/libc-2.20.so)
==6939== by 0x51E36FF: ??? (in
/usr/local/stow/spice-gtk/lib/libspice-client-glib-2.0.so.8.5.0)
==6939== by 0xCF0C18F: ???
==6939== Address 0xff15f90 is 0 bytes inside a block of size 536 free'd
==6939== at 0x4A07CE9: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939== by 0x394B606466: libusb_exit (core.c:2041)
==6939== by 0x4ECC590: spice_usb_device_manager_finalize (usb-device-manager.c:371)
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 7b27516..e11eae0 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -767,6 +767,14 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel,
g_ptr_array_add(self->priv->channels, channel);
spice_usb_device_manager_check_redir_on_connect(self, channel);
+
+ /*
+ * add a reference to ourself, to make sure the libusb context is
+ * alive as long as the channel is.
+ * TODO: moving to gusb could help here too.
+ */
+ g_object_ref(self);
+ g_object_weak_ref(G_OBJECT(channel), (GWeakNotify)g_object_unref, self);
}
static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
commit a56c7296a61df3aba35baa498d2b3d5afc2af6bc
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 17:51:58 2014 +0100
usb: return early if channel is not usb
Return early if channel is not USB, replace:
if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
/* code */
}
with
if (!SPICE_IS_USBREDIR_CHANNEL(channel))
return;
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index a7b1140..7b27516 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -758,14 +758,15 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel,
{
SpiceUsbDeviceManager *self = user_data;
- if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
- spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel),
- self->priv->context);
- spice_channel_connect(channel);
- g_ptr_array_add(self->priv->channels, channel);
+ if (!SPICE_IS_USBREDIR_CHANNEL(channel))
+ return;
- spice_usb_device_manager_check_redir_on_connect(self, channel);
- }
+ spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel),
+ self->priv->context);
+ spice_channel_connect(channel);
+ g_ptr_array_add(self->priv->channels, channel);
+
+ spice_usb_device_manager_check_redir_on_connect(self, channel);
}
static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
@@ -773,8 +774,10 @@ static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
{
SpiceUsbDeviceManager *self = user_data;
- if (SPICE_IS_USBREDIR_CHANNEL(channel))
- g_ptr_array_remove(self->priv->channels, channel);
+ if (!SPICE_IS_USBREDIR_CHANNEL(channel))
+ return;
+
+ g_ptr_array_remove(self->priv->channels, channel);
}
static void spice_usb_device_manager_auto_connect_cb(GObject *gobject,
commit ff25f3eacb1776a754147cd57c76882392382030
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 12 15:55:23 2014 +0100
session: disconnect in idle
This is a workaround for existing clients such as virt-viewer that do
not hold a reference to their sessions when calling
spice_session_disconnect() and crash now that channels are removed from
session during the call. They expect disconnection events to be deferred
instead, let's defer actual disconnection to idle time for public
disconnect API for compatibility reasons (it is still recommended to fix
client code, for eventual future iterations)
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index f87e7ea..ba4ec1d 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -99,7 +99,7 @@ struct _SpiceSessionPrivate {
GList *migration_left;
SpiceSessionMigration migration_state;
gboolean full_migration; /* seamless migration indicator */
- gooblean disconnecting;
+ guint disconnecting;
gboolean migrate_wait_init;
guint after_main_init;
gboolean for_migration;
@@ -258,6 +258,31 @@ static void spice_session_init(SpiceSession *session)
}
static void
+session_disconnect(SpiceSession *self)
+{
+ SpiceSessionPrivate *s;
+ struct channel *item;
+ RingItem *ring, *next;
+
+ s = self->priv;
+ s->cmain = NULL;
+
+ for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
+ next = ring_next(&s->channels, ring);
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+ spice_session_channel_destroy(self, item->channel);
+ }
+
+ s->connection_id = 0;
+
+ g_free(s->name);
+ s->name = NULL;
+ memset(s->uuid, 0, sizeof(s->uuid));
+
+ spice_session_abort_migration(self);
+}
+
+static void
spice_session_dispose(GObject *gobject)
{
SpiceSession *session = SPICE_SESSION(gobject);
@@ -265,11 +290,12 @@ spice_session_dispose(GObject *gobject)
SPICE_DEBUG("session dispose");
- spice_session_disconnect(session);
+ session_disconnect(session);
g_warn_if_fail(s->migration == NULL);
g_warn_if_fail(s->migration_left == NULL);
g_warn_if_fail(s->after_main_init == 0);
+ g_warn_if_fail(s->disconnecting == 0);
g_clear_object(&s->audio_manager);
g_clear_object(&s->usb_manager);
@@ -1384,7 +1410,7 @@ gboolean spice_session_connect(SpiceSession *session)
s = session->priv;
g_return_val_if_fail(!s->disconnecting, FALSE);
- spice_session_disconnect(session);
+ session_disconnect(session);
s->client_provided_sockets = FALSE;
@@ -1419,7 +1445,7 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd)
s = session->priv;
g_return_val_if_fail(!s->disconnecting, FALSE);
- spice_session_disconnect(session);
+ session_disconnect(session);
s->client_provided_sockets = TRUE;
@@ -1576,7 +1602,7 @@ void spice_session_abort_migration(SpiceSession *session)
end:
g_list_free(s->migration_left);
s->migration_left = NULL;
- spice_session_disconnect(s->migration);
+ session_disconnect(s->migration);
g_object_unref(s->migration);
s->migration = NULL;
@@ -1616,7 +1642,7 @@ void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
if (g_list_length(s->migration_left) == 0) {
CHANNEL_DEBUG(channel, "migration: all channel migrated, success");
- spice_session_disconnect(s->migration);
+ session_disconnect(s->migration);
g_object_unref(s->migration);
s->migration = NULL;
spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_NONE);
@@ -1719,6 +1745,18 @@ gboolean spice_session_get_read_only(SpiceSession *self)
return self->priv->read_only;
}
+static gboolean session_disconnect_idle(SpiceSession *self)
+{
+ SpiceSessionPrivate *s = self->priv;
+
+ session_disconnect(self);
+ s->disconnecting = 0;
+
+ g_object_unref(self);
+
+ return G_SOURCE_REMOVE;
+}
+
/**
* spice_session_disconnect:
* @session:
@@ -1728,37 +1766,17 @@ gboolean spice_session_get_read_only(SpiceSession *self)
void spice_session_disconnect(SpiceSession *session)
{
SpiceSessionPrivate *s;
- struct channel *item;
- RingItem *ring, *next;
g_return_if_fail(SPICE_IS_SESSION(session));
- g_return_if_fail(session->priv != NULL);
s = session->priv;
SPICE_DEBUG("session: disconnecting %d", s->disconnecting);
- if (s->disconnecting)
+ if (s->disconnecting != 0)
return;
g_object_ref(session);
- s->disconnecting = TRUE;
- s->cmain = NULL;
-
- for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
- next = ring_next(&s->channels, ring);
- item = SPICE_CONTAINEROF(ring, struct channel, link);
- spice_session_channel_destroy(session, item->channel);
- }
-
- s->connection_id = 0;
-
- g_free(s->name);
- s->name = NULL;
- memset(s->uuid, 0, sizeof(s->uuid));
-
- spice_session_abort_migration(session);
- s->disconnecting = FALSE;
- g_object_unref(session);
+ s->disconnecting = g_idle_add((GSourceFunc)session_disconnect_idle, session);
}
/**
commit 45f417a5f8329804f6d6cce1ba3aeefff3385f1d
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 12 15:55:23 2014 +0100
session: keep a reference on disconnect
It is idiomatic for client code to clean up its reference on channel
disconnection. Keeping a reference during disconnect helps solving
potential crashes if the session is unref'ed during callbacks.
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 8059f2f..f87e7ea 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1740,6 +1740,7 @@ void spice_session_disconnect(SpiceSession *session)
if (s->disconnecting)
return;
+ g_object_ref(session);
s->disconnecting = TRUE;
s->cmain = NULL;
@@ -1757,6 +1758,7 @@ void spice_session_disconnect(SpiceSession *session)
spice_session_abort_migration(session);
s->disconnecting = FALSE;
+ g_object_unref(session);
}
/**
commit 38bf189f0502a1f1570fb5825b571f45f2f47ba5
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 12 15:59:05 2014 +0100
session: remove sticky disconnecting flag
This used to help prevent double-unref when channel were considered part
of the session as long as they lived. Now it shouldn't be required
anymore
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index a7f128a..8059f2f 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1382,9 +1382,9 @@ gboolean spice_session_connect(SpiceSession *session)
g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
s = session->priv;
+ g_return_val_if_fail(!s->disconnecting, FALSE);
spice_session_disconnect(session);
- s->disconnecting = FALSE;
s->client_provided_sockets = FALSE;
@@ -1417,9 +1417,9 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd)
g_return_val_if_fail(fd >= -1, FALSE);
s = session->priv;
+ g_return_val_if_fail(!s->disconnecting, FALSE);
spice_session_disconnect(session);
- s->disconnecting = FALSE;
s->client_provided_sockets = TRUE;
@@ -1756,8 +1756,7 @@ void spice_session_disconnect(SpiceSession *session)
memset(s->uuid, 0, sizeof(s->uuid));
spice_session_abort_migration(session);
- /* we leave disconnecting = TRUE, so that spice_channel_disconnect()
- is not called multiple times */
+ s->disconnecting = FALSE;
}
/**
commit 5b41e43d0b178219ce295478bf9b35ce122f29aa
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Sun Nov 9 21:55:18 2014 +0100
channel: deprecate spice_channel_destroy()
This function is somewhat useless, and dangerous since it is calling
g_object_unref() behind your back (although this is mentioned in the
doc, I consider this a bad practice).
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 7c18d87..ea0ed34 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2038,8 +2038,12 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
* spice_channel_destroy:
* @channel:
*
- * Disconnect and unref the @channel. Called by @spice_session_channel_destroy()
+ * Disconnect and unref the @channel.
*
+ * Deprecated: 0.27: this function has been deprecated because it is
+ * misleading, the object is not actually destroyed. Instead, it is
+ * recommended to call explicitely spice_channel_disconnect() and
+ * g_object_unref().
**/
void spice_channel_destroy(SpiceChannel *channel)
{
diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h
index 1c303b4..8d07383 100644
--- a/gtk/spice-channel.h
+++ b/gtk/spice-channel.h
@@ -107,7 +107,6 @@ GType spice_channel_get_type(void);
typedef void (*spice_msg_handler)(SpiceChannel *channel, SpiceMsgIn *in);
SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id);
-void spice_channel_destroy(SpiceChannel *channel);
gboolean spice_channel_connect(SpiceChannel *channel);
gboolean spice_channel_open_fd(SpiceChannel *channel, int fd);
void spice_channel_disconnect(SpiceChannel *channel, SpiceChannelEvent reason);
@@ -118,6 +117,8 @@ gboolean spice_channel_flush_finish(SpiceChannel *channel, GAsyncResult *result,
#ifndef SPICE_DISABLE_DEPRECATED
SPICE_DEPRECATED
void spice_channel_set_capability(SpiceChannel *channel, guint32 cap);
+SPICE_DEPRECATED
+void spice_channel_destroy(SpiceChannel *channel);
#endif
const gchar* spice_channel_type_to_string(gint type);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 6c5e03a..a7f128a 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1756,9 +1756,8 @@ void spice_session_disconnect(SpiceSession *session)
memset(s->uuid, 0, sizeof(s->uuid));
spice_session_abort_migration(session);
- /* we leave disconnecting = TRUE, so that spice_channel_destroy()
- is not called multiple times on channels that are in pending
- destroy state. */
+ /* we leave disconnecting = TRUE, so that spice_channel_disconnect()
+ is not called multiple times */
}
/**
@@ -2066,7 +2065,8 @@ static void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *c
g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_DESTROY], 0, channel);
g_clear_object(&channel->priv->session);
- spice_channel_destroy(channel);
+ spice_channel_disconnect(channel, SPICE_CHANNEL_NONE);
+ g_object_unref(channel);
}
G_GNUC_INTERNAL
commit 80f2f98b2c9e908c44c419af543a782804457bec
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 13:55:18 2014 +0100
display: don't reschedule stream if disconnected from session
Avoid the following critical when a channel is disconnected with a
pending stream (the streams are cleared on channel reset, after
coroutine exit)
(process:17188): GSpice-CRITICAL **: spice_session_get_mm_time: assertion 'session != NULL' failed
#0 0x00007ffff71c24e5 in spice_session_get_mm_time (session=0x0) at spice-session.c:1999
#1 0x00007ffff71d438c in display_stream_schedule (st=0xa33040) at channel-display.c:1014
#2 0x00007ffff71d4a09 in display_stream_render (st=0xa33040,
st at entry=<error reading variable: value has been optimized out>) at channel-display.c:1165
#3 0x0000003e1944a553 in g_timeout_dispatch (source=0xad64e0, callback=<optimized out>, user_data=<optimized out>) at gmain.c:4520
#4 0x0000003e19449aeb in g_main_context_dispatch (context=0x6a32b0) at gmain.c:3111
#5 0x0000003e19449aeb in g_main_context_dispatch (context=context at entry=0x6a32b0) at gmain.c:3710
#6 0x0000003e19449e88 in g_main_context_iterate (context=0x6a32b0, block=block at entry=1, dispatch=dispatch at entry=1, self=<optimized out>) at gmain.c:3781
#7 0x0000003e1944a1b2 in g_main_loop_run (loop=0x97e200) at gmain.c:3975
#8 0x0000003e1c9ebb35 in gtk_main () at gtkmain.c:1207
#9 0x0000000000430185 in main (argc=1, argv=0x7fffffffdcb8) at virt-viewer-main.c:119
diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index 940a5a7..17e2f6e 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -1003,15 +1003,16 @@ static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn *in)
/* coroutine or main context */
static gboolean display_stream_schedule(display_stream *st)
{
+ SpiceSession *session = spice_channel_get_session(st->channel);
guint32 time, d;
SpiceStreamDataHeader *op;
SpiceMsgIn *in;
SPICE_DEBUG("%s", __FUNCTION__);
- if (st->timeout)
+ if (st->timeout || !session)
return TRUE;
- time = spice_session_get_mm_time(spice_channel_get_session(st->channel));
+ time = spice_session_get_mm_time(session);
in = g_queue_peek_head(st->msgq);
if (in == NULL) {
commit 8943d232995147214e39314ec375d3e6f3a91bff
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Sun Nov 9 21:47:41 2014 +0100
session: remove channels on disconnect
A channel is considered to be part of a session as long as it is
alive. However, this model is problematic, since library user may hold
channel references, and thus the channel will remain in the
session. Calling spice_session_disconnect() several time will end up
calling spice_channel_destroy(), releasing references that aren't owned
by the session. This usually causes crashes, in particular with language
bindings that do not deal well with a library model where objects can't
be referenced at will.
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 154dacb..7c18d87 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -152,9 +152,6 @@ static void spice_channel_dispose(GObject *gobject)
CHANNEL_DEBUG(channel, "%s %p", __FUNCTION__, gobject);
- if (c->session)
- spice_session_channel_destroy(c->session, channel);
-
spice_channel_disconnect(channel, SPICE_CHANNEL_CLOSED);
if (c->session) {
@@ -2041,7 +2038,7 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
* spice_channel_destroy:
* @channel:
*
- * Disconnect and unref the @channel. Called by @spice_session_disconnect()
+ * Disconnect and unref the @channel. Called by @spice_session_channel_destroy()
*
**/
void spice_channel_destroy(SpiceChannel *channel)
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 7fc71cf..46938ff 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -48,7 +48,6 @@ gboolean spice_session_get_client_provided_socket(SpiceSession *session);
GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
gboolean *use_tls, GError **error);
void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel);
-void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel);
void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel);
void spice_session_set_mm_time(SpiceSession *session, guint32 time);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 8527801..6c5e03a 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -210,6 +210,8 @@ enum {
static guint signals[SPICE_SESSION_LAST_SIGNAL];
+static void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel);
+
static void update_proxy(SpiceSession *self, const gchar *str)
{
SpiceSessionPrivate *s = self->priv;
@@ -1462,8 +1464,10 @@ void spice_session_switching_disconnect(SpiceSession *self)
for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
next = ring_next(&s->channels, ring);
item = SPICE_CONTAINEROF(ring, struct channel, link);
- if (item->channel != s->cmain)
- spice_channel_destroy(item->channel); /* /!\ item and channel are destroy() after this call */
+
+ if (item->channel == s->cmain)
+ continue;
+ spice_session_channel_destroy(self, item->channel);
}
g_warn_if_fail(!ring_is_empty(&s->channels)); /* ring_get_length() == 1 */
@@ -1742,7 +1746,7 @@ void spice_session_disconnect(SpiceSession *session)
for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
next = ring_next(&s->channels, ring);
item = SPICE_CONTAINEROF(ring, struct channel, link);
- spice_channel_destroy(item->channel); /* /!\ item and channel are destroy() after this call */
+ spice_session_channel_destroy(session, item->channel);
}
s->connection_id = 0;
@@ -2030,8 +2034,7 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_NEW], 0, channel);
}
-G_GNUC_INTERNAL
-void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
+static void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
{
g_return_if_fail(SPICE_IS_SESSION(session));
g_return_if_fail(SPICE_IS_CHANNEL(channel));
@@ -2061,6 +2064,9 @@ void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
free(item);
g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_DESTROY], 0, channel);
+
+ g_clear_object(&channel->priv->session);
+ spice_channel_destroy(channel);
}
G_GNUC_INTERNAL
commit a67e5df1496812e6bc8405be95144f0eddc334b8
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 12:06:19 2014 +0100
session: move SpiceSessionPrivate out of headers
Make sure none of the SpiceSessionPrivate fields are accessed directly anymore
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index c9efba3..7fc71cf 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -37,90 +37,8 @@ typedef struct _PhodavServer PhodavServer;
G_BEGIN_DECLS
-#define IMAGES_CACHE_SIZE_DEFAULT (1024 * 1024 * 80)
-#define MIN_GLZ_WINDOW_SIZE_DEFAULT (1024 * 1024 * 12)
-#define MAX_GLZ_WINDOW_SIZE_DEFAULT MIN((LZ_MAX_WINDOW_SIZE * 4), 1024 * 1024 * 64)
#define WEBDAV_MAGIC_SIZE 16
-struct _SpiceSessionPrivate {
- char *host;
- char *port;
- char *tls_port;
- char *username;
- char *password;
- char *ca_file;
- char *ciphers;
- GByteArray *pubkey;
- GByteArray *ca;
- char *cert_subject;
- guint verify;
- gboolean read_only;
- SpiceURI *proxy;
- gchar *shared_dir;
-
- /* whether to enable audio */
- gboolean audio;
-
- /* whether to enable smartcard event forwarding to the server */
- gboolean smartcard;
-
- /* list of certificates to use for the software smartcard reader if
- * enabled. For now, it has to contain exactly 3 certificates for
- * the software reader to be functional
- */
- GStrv smartcard_certificates;
-
- /* path to the local certificate database to use to lookup the
- * certificates stored in 'certificates'. If NULL, libcacard will
- * fallback to using a default database.
- */
- char * smartcard_db;
-
- /* whether to enable USB redirection */
- gboolean usbredir;
-
- /* Set when a usbredir channel has requested the keyboard grab to be
- temporarily released (because it is going to invoke policykit) */
- gboolean inhibit_keyboard_grab;
-
- GStrv disable_effects;
- GStrv secure_channels;
- gint color_depth;
-
- int connection_id;
- int protocol;
- SpiceChannel *cmain; /* weak reference */
- Ring channels;
- guint32 mm_time;
- gboolean client_provided_sockets;
- guint64 mm_time_at_clock;
- SpiceSession *migration;
- GList *migration_left;
- SpiceSessionMigration migration_state;
- gboolean full_migration; /* seamless migration indicator */
- gboolean disconnecting;
- gboolean migrate_wait_init;
- guint after_main_init;
- gboolean for_migration;
-
- display_cache *images;
- display_cache *palettes;
- SpiceGlzDecoderWindow *glz_window;
- int images_cache_size;
- int glz_window_size;
- uint32_t pci_ram_size;
- uint32_t n_display_channels;
- guint8 uuid[WEBDAV_MAGIC_SIZE];
- gchar *name;
-
- /* associated objects */
- SpiceAudio *audio_manager;
- SpiceUsbDeviceManager *usb_manager;
- SpicePlaybackChannel *playback_channel;
- PhodavServer *webdav;
- guint8 webdav_magic[16];
-};
-
SpiceSession *spice_session_new_from_session(SpiceSession *session);
void spice_session_set_connection_id(SpiceSession *session, int id);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 5ddcd5c..8527801 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -39,6 +39,90 @@ struct channel {
RingItem link;
};
+#define IMAGES_CACHE_SIZE_DEFAULT (1024 * 1024 * 80)
+#define MIN_GLZ_WINDOW_SIZE_DEFAULT (1024 * 1024 * 12)
+#define MAX_GLZ_WINDOW_SIZE_DEFAULT MIN((LZ_MAX_WINDOW_SIZE * 4), 1024 * 1024 * 64)
+
+struct _SpiceSessionPrivate {
+ char *host;
+ char *port;
+ char *tls_port;
+ char *username;
+ char *password;
+ char *ca_file;
+ char *ciphers;
+ GByteArray *pubkey;
+ GByteArray *ca;
+ char *cert_subject;
+ guint verify;
+ gboolean read_only;
+ SpiceURI *proxy;
+ gchar *shared_dir;
+
+ /* whether to enable audio */
+ gboolean audio;
+
+ /* whether to enable smartcard event forwarding to the server */
+ gboolean smartcard;
+
+ /* list of certificates to use for the software smartcard reader if
+ * enabled. For now, it has to contain exactly 3 certificates for
+ * the software reader to be functional
+ */
+ GStrv smartcard_certificates;
+
+ /* path to the local certificate database to use to lookup the
+ * certificates stored in 'certificates'. If NULL, libcacard will
+ * fallback to using a default database.
+ */
+ char * smartcard_db;
+
+ /* whether to enable USB redirection */
+ gboolean usbredir;
+
+ /* Set when a usbredir channel has requested the keyboard grab to be
+ temporarily released (because it is going to invoke policykit) */
+ gboolean inhibit_keyboard_grab;
+
+ GStrv disable_effects;
+ GStrv secure_channels;
+ gint color_depth;
+
+ int connection_id;
+ int protocol;
+ SpiceChannel *cmain; /* weak reference */
+ Ring channels;
+ guint32 mm_time;
+ gboolean client_provided_sockets;
+ guint64 mm_time_at_clock;
+ SpiceSession *migration;
+ GList *migration_left;
+ SpiceSessionMigration migration_state;
+ gboolean full_migration; /* seamless migration indicator */
+ gooblean disconnecting;
+ gboolean migrate_wait_init;
+ guint after_main_init;
+ gboolean for_migration;
+
+ display_cache *images;
+ display_cache *palettes;
+ SpiceGlzDecoderWindow *glz_window;
+ int images_cache_size;
+ int glz_window_size;
+ uint32_t pci_ram_size;
+ uint32_t n_display_channels;
+ guint8 uuid[16];
+ gchar *name;
+
+ /* associated objects */
+ SpiceAudio *audio_manager;
+ SpiceUsbDeviceManager *usb_manager;
+ SpicePlaybackChannel *playback_channel;
+ PhodavServer *webdav;
+ guint8 webdav_magic[WEBDAV_MAGIC_SIZE];
+};
+
+
/**
* SECTION:spice-session
* @short_description: handles connection details, and active channels
commit e0514dc3f8ebcdd2d97bcc5e561a391a0deae61f
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 12:02:06 2014 +0100
gtk: do not require glib session private fields
Use GObject object association for session helpers.
GtkSession and DesktopIntegration are in the gtk library SpiceSession is
in glib one. So far we had the SessionPriv structure shared between the
two libraries, so they could fit their pointers there. But this is no
longer possible when moving the private structure in .c. We could add
more accessors, but they would need to be in public API, and this isn't
supposed to be accessed by API users.
diff --git a/gtk/desktop-integration.c b/gtk/desktop-integration.c
index 145fa6a..c366fd0 100644
--- a/gtk/desktop-integration.c
+++ b/gtk/desktop-integration.c
@@ -187,9 +187,6 @@ static void spice_desktop_integration_class_init(SpiceDesktopIntegrationClass *k
g_type_class_add_private(klass, sizeof(SpiceDesktopIntegrationPrivate));
}
-/* ------------------------------------------------------------------ */
-/* public methods */
-
SpiceDesktopIntegration *spice_desktop_integration_get(SpiceSession *session)
{
SpiceDesktopIntegration *self;
@@ -198,10 +195,10 @@ SpiceDesktopIntegration *spice_desktop_integration_get(SpiceSession *session)
g_return_val_if_fail(session != NULL, NULL);
g_static_mutex_lock(&mutex);
- self = session->priv->desktop_integration;
+ self = g_object_get_data(G_OBJECT(session), "spice-desktop");
if (self == NULL) {
self = g_object_new(SPICE_TYPE_DESKTOP_INTEGRATION, NULL);
- session->priv->desktop_integration = self;
+ g_object_set_data_full(G_OBJECT(session), "spice-desktop", self, g_object_unref);
}
g_static_mutex_unlock(&mutex);
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
index 701950d..de01358 100644
--- a/gtk/spice-gtk-session.c
+++ b/gtk/spice-gtk-session.c
@@ -1119,10 +1119,10 @@ SpiceGtkSession *spice_gtk_session_get(SpiceSession *session)
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
g_static_mutex_lock(&mutex);
- self = session->priv->gtk_session;
+ self = g_object_get_data(G_OBJECT(session), "spice-gtk-session");
if (self == NULL) {
self = g_object_new(SPICE_TYPE_GTK_SESSION, "session", session, NULL);
- session->priv->gtk_session = self;
+ g_object_set_data_full(G_OBJECT(session), "spice-gtk-session", self, g_object_unref);
}
g_static_mutex_unlock(&mutex);
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 98c3f72..c9efba3 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -115,8 +115,6 @@ struct _SpiceSessionPrivate {
/* associated objects */
SpiceAudio *audio_manager;
- SpiceDesktopIntegration *desktop_integration;
- SpiceGtkSession *gtk_session;
SpiceUsbDeviceManager *usb_manager;
SpicePlaybackChannel *playback_channel;
PhodavServer *webdav;
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 02ebd74..5ddcd5c 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -186,8 +186,6 @@ spice_session_dispose(GObject *gobject)
g_warn_if_fail(s->after_main_init == 0);
g_clear_object(&s->audio_manager);
- g_clear_object(&s->desktop_integration);
- g_clear_object(&s->gtk_session);
g_clear_object(&s->usb_manager);
g_clear_object(&s->proxy);
g_clear_object(&s->webdav);
commit e02733abe9b43b6b84da1e240bf037a656ab98c3
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:57:47 2014 +0100
usb: move device manager initialization to session
Use session accessors to initialize the device manager.
Add missing session parameter check (public API).
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 2e837f2..02ebd74 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2347,6 +2347,40 @@ SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context)
return self;
}
+/**
+ * spice_usb_device_manager_get:
+ * @session: #SpiceSession for which to get the #SpiceUsbDeviceManager
+ *
+ * Gets the #SpiceUsbDeviceManager associated with the passed in #SpiceSession.
+ * A new #SpiceUsbDeviceManager instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to the #SpiceUsbDeviceManager associated with the passed in #SpiceSession
+ */
+SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
+ GError **err)
+{
+ SpiceUsbDeviceManager *self;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ g_static_mutex_lock(&mutex);
+ self = session->priv->usb_manager;
+ if (self == NULL) {
+ self = g_initable_new(SPICE_TYPE_USB_DEVICE_MANAGER, NULL, err,
+ "session", session, NULL);
+ session->priv->usb_manager = self;
+ }
+ g_static_mutex_unlock(&mutex);
+
+ return self;
+}
+
G_GNUC_INTERNAL
gboolean spice_session_get_audio_enabled(SpiceSession *session)
{
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index f80b657..a7b1140 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -1300,39 +1300,6 @@ static SpiceUsbredirChannel *spice_usb_device_manager_get_channel_for_dev(
/* public api */
/**
- * spice_usb_device_manager_get:
- * @session: #SpiceSession for which to get the #SpiceUsbDeviceManager
- *
- * Gets the #SpiceUsbDeviceManager associated with the passed in #SpiceSession.
- * A new #SpiceUsbDeviceManager instance will be created the first time this
- * function is called for a certain #SpiceSession.
- *
- * Note that this function returns a weak reference, which should not be used
- * after the #SpiceSession itself has been unref-ed by the caller.
- *
- * Returns: (transfer none): a weak reference to the #SpiceUsbDeviceManager associated with the passed in #SpiceSession
- */
-SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
- GError **err)
-{
- SpiceUsbDeviceManager *self;
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
-
- g_return_val_if_fail(err == NULL || *err == NULL, NULL);
-
- g_static_mutex_lock(&mutex);
- self = session->priv->usb_manager;
- if (self == NULL) {
- self = g_initable_new(SPICE_TYPE_USB_DEVICE_MANAGER, NULL, err,
- "session", session, NULL);
- session->priv->usb_manager = self;
- }
- g_static_mutex_unlock(&mutex);
-
- return self;
-}
-
-/**
* spice_usb_device_manager_get_devices_with_filter:
* @manager: the #SpiceUsbDeviceManager manager
* @filter: (allow-none): filter string for selecting which devices to return,
commit 5b0c345e744964e50a3c915ef5d756b7399c2b34
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:56:42 2014 +0100
webdav: move initialization to session
Use session accessors to initialize the webdav server
diff --git a/gtk/channel-webdav.c b/gtk/channel-webdav.c
index dbb8730..94f3ef3 100644
--- a/gtk/channel-webdav.c
+++ b/gtk/channel-webdav.c
@@ -694,19 +694,14 @@ end:
g_object_unref(gaddr);
}
-static PhodavServer* webdav_server_new(SpiceSession *session)
+G_GNUC_INTERNAL
+PhodavServer* channel_webdav_server_new(SpiceSession *session)
{
PhodavServer *dav;
SoupServer *server;
SoupSocket *listener;
- int i;
-
- g_warn_if_fail(!session->priv->webdav);
dav = phodav_server_new(0, spice_session_get_shared_dir(session));
- session->priv->webdav = dav;
- for (i = 0; i < sizeof(session->priv->webdav_magic); i++)
- session->priv->webdav_magic[i] = g_random_int_range(0, 255);
server = phodav_server_get_soup_server(dav);
listener = soup_server_get_listener(server);
@@ -723,21 +718,12 @@ static PhodavServer* phodav_server_get(SpiceSession *session, gint *port)
g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
#ifdef USE_PHODAV
- PhodavServer *self = NULL;
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
-
- g_static_mutex_lock(&mutex);
- self = session->priv->webdav;
- if (self == NULL) {
- self = webdav_server_new(session);
- phodav_server_run(self);
- }
- g_static_mutex_unlock(&mutex);
+ PhodavServer *server = spice_session_get_webdav_server(session);
if (port)
- *port = phodav_server_get_port(self);
+ *port = phodav_server_get_port(server);
- return self;
+ return server;
#else
g_return_val_if_reached(NULL);
#endif
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 95fc078..98c3f72 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -178,6 +178,8 @@ gboolean spice_session_get_smartcard_enabled(SpiceSession *session);
gboolean spice_session_get_usbredir_enabled(SpiceSession *session);
const guint8* spice_session_get_webdav_magic(SpiceSession *session);
+PhodavServer *spice_session_get_webdav_server(SpiceSession *session);
+PhodavServer* channel_webdav_server_new(SpiceSession *session);
guint spice_session_get_n_display_channels(SpiceSession *session);
void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel);
gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 5c1966e..2e837f2 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2379,6 +2379,29 @@ const guint8* spice_session_get_webdav_magic(SpiceSession *session)
return session->priv->webdav_magic;
}
+G_GNUC_INTERNAL
+PhodavServer* spice_session_get_webdav_server(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+#ifdef USE_PHODAV
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+ int i;
+
+ g_static_mutex_lock(&mutex);
+ if (!session->priv->webdav) {
+ for (i = 0; i < sizeof(session->priv->webdav_magic); i++)
+ session->priv->webdav_magic[i] = g_random_int_range(0, 255);
+
+ session->priv->webdav = channel_webdav_server_new(session);
+ phodav_server_run(session->priv->webdav);
+ }
+ g_static_mutex_unlock(&mutex);
+#endif
+
+ return session->priv->webdav;
+}
+
/**
* spice_session_is_for_migration:
* @session: a Spice session
commit a88a31902a0998ad38f0206ddb5ff6c0c6ea417b
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 18:11:01 2014 +0100
Rename display_channels_count/n_display_channels
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index b62da60..7af4a2e 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -1298,7 +1298,7 @@ static gboolean timer_set_display(gpointer data)
/* ensure we have an explicit monitor configuration at least for
number of display channels */
- for (i = 0; i < spice_session_get_display_channels_count(session); i++)
+ for (i = 0; i < spice_session_get_n_display_channels(session); i++)
if (!c->display[i].enabled_set) {
SPICE_DEBUG("Not sending monitors config, missing monitors");
return FALSE;
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index e150fc7..95fc078 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -109,7 +109,7 @@ struct _SpiceSessionPrivate {
int images_cache_size;
int glz_window_size;
uint32_t pci_ram_size;
- uint32_t display_channels_count;
+ uint32_t n_display_channels;
guint8 uuid[WEBDAV_MAGIC_SIZE];
gchar *name;
@@ -157,7 +157,7 @@ void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size);
void spice_session_set_caches_hints(SpiceSession *session,
uint32_t pci_ram_size,
- uint32_t display_channels_count);
+ uint32_t n_display_channels);
void spice_session_get_caches(SpiceSession *session,
display_cache **images,
SpiceGlzDecoderWindow **glz_window);
@@ -178,7 +178,7 @@ gboolean spice_session_get_smartcard_enabled(SpiceSession *session);
gboolean spice_session_get_usbredir_enabled(SpiceSession *session);
const guint8* spice_session_get_webdav_magic(SpiceSession *session);
-guint spice_session_get_display_channels_count(SpiceSession *session);
+guint spice_session_get_n_display_channels(SpiceSession *session);
void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel);
gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index a2e79bb..5c1966e 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2177,14 +2177,14 @@ void spice_session_get_caches(SpiceSession *session,
G_GNUC_INTERNAL
void spice_session_set_caches_hints(SpiceSession *session,
uint32_t pci_ram_size,
- uint32_t display_channels_count)
+ uint32_t n_display_channels)
{
g_return_if_fail(SPICE_IS_SESSION(session));
SpiceSessionPrivate *s = session->priv;
s->pci_ram_size = pci_ram_size;
- s->display_channels_count = display_channels_count;
+ s->n_display_channels = n_display_channels;
/* TODO: when setting cache and window size, we should consider the client's
* available memory and the number of display channels */
@@ -2199,11 +2199,11 @@ void spice_session_set_caches_hints(SpiceSession *session,
}
G_GNUC_INTERNAL
-guint spice_session_get_display_channels_count(SpiceSession *session)
+guint spice_session_get_n_display_channels(SpiceSession *session)
{
g_return_val_if_fail(session != NULL, 0);
- return session->priv->display_channels_count;
+ return session->priv->n_display_channels;
}
G_GNUC_INTERNAL
commit 3623476d0dc6e4dcac24543a5918123db7b5a08f
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:52:13 2014 +0100
session: add and use internal accessors
Avoid dereferencing session private data directly, and use accessors
instead.
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index bf7c204..b62da60 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -1298,7 +1298,7 @@ static gboolean timer_set_display(gpointer data)
/* ensure we have an explicit monitor configuration at least for
number of display channels */
- for (i = 0; i < session->priv->display_channels_count; i++)
+ for (i = 0; i < spice_session_get_display_channels_count(session); i++)
if (!c->display[i].enabled_set) {
SPICE_DEBUG("Not sending monitors config, missing monitors");
return FALSE;
@@ -2132,7 +2132,8 @@ static gboolean migrate_connect(gpointer data)
/* the migration process is in 2 steps, first the main channel and
then the rest of the channels */
- mig->session->priv->cmain = migrate_channel_connect(mig, SPICE_CHANNEL_MAIN, 0);
+ spice_session_set_main_channel(mig->session,
+ migrate_channel_connect(mig, SPICE_CHANNEL_MAIN, 0));
return FALSE;
}
@@ -2156,13 +2157,11 @@ static void main_migrate_connect(SpiceChannel *channel,
CHANNEL_DEBUG(channel, "migrate connect");
session = spice_channel_get_session(channel);
- if (session->priv->migration != NULL)
- goto end;
-
mig.session = spice_session_new_from_session(session);
if (mig.session == NULL)
goto end;
- session->priv->migration = mig.session;
+ if (!spice_session_set_migration_session(session, mig.session))
+ goto end;
main_priv->migrate_data = &mig;
diff --git a/gtk/channel-webdav.c b/gtk/channel-webdav.c
index 0529b59..dbb8730 100644
--- a/gtk/channel-webdav.c
+++ b/gtk/channel-webdav.c
@@ -336,13 +336,11 @@ static void magic_written(GObject *source_object,
SpiceWebdavChannelPrivate *c = self->priv;
gssize bytes_written;
GError *err = NULL;
- SpiceSession *session;
- session = spice_channel_get_session(SPICE_CHANNEL(self));
bytes_written = g_output_stream_write_finish(G_OUTPUT_STREAM(source_object),
res, &err);
- if (err || bytes_written != sizeof(session->priv->webdav_magic))
+ if (err || bytes_written != WEBDAV_MAGIC_SIZE)
goto error;
client_start_read(self, client);
@@ -396,7 +394,7 @@ static void client_connected(GObject *source_object,
g_object_unref(output);
g_output_stream_write_async(g_io_stream_get_output_stream(G_IO_STREAM(conn)),
- session->priv->webdav_magic, sizeof(session->priv->webdav_magic),
+ spice_session_get_webdav_magic(session), WEBDAV_MAGIC_SIZE,
G_PRIORITY_DEFAULT, c->cancellable,
magic_written, client);
return;
@@ -654,7 +652,7 @@ static void new_connection(SoupSocket *sock,
GSocketAddress *gaddr;
GInetAddress *iaddr;
guint port;
- guint8 magic[16];
+ guint8 magic[WEBDAV_MAGIC_SIZE];
gsize nread;
gboolean success = FALSE;
SoupSocketIOStatus status;
@@ -680,7 +678,7 @@ static void new_connection(SoupSocket *sock,
g_object_set(new, "non-blocking", TRUE, NULL);
/* check we got the right magic */
- if (memcmp(session->priv->webdav_magic, magic, sizeof(magic))) {
+ if (memcmp(spice_session_get_webdav_magic(session), magic, sizeof(magic))) {
g_warn_if_reached();
goto end;
}
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 94f980f..154dacb 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -1987,7 +1987,7 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
break;
case SPICE_CHANNEL_PLAYBACK:
case SPICE_CHANNEL_RECORD: {
- if (!s->priv->audio) {
+ if (!spice_session_get_audio_enabled(s)) {
g_debug("audio channel is disabled, not creating it");
return NULL;
}
@@ -1997,7 +1997,7 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
}
#ifdef USE_SMARTCARD
case SPICE_CHANNEL_SMARTCARD: {
- if (!s->priv->smartcard) {
+ if (!spice_session_get_smartcard_enabled(s)) {
g_debug("smartcard channel is disabled, not creating it");
return NULL;
}
@@ -2007,7 +2007,7 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
#endif
#ifdef USE_USBREDIR
case SPICE_CHANNEL_USBREDIR: {
- if (!s->priv->usbredir) {
+ if (!spice_session_get_usbredir_enabled(s)) {
g_debug("usbredir channel is disabled, not creating it");
return NULL;
}
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 6d8be8d..e150fc7 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -40,6 +40,7 @@ G_BEGIN_DECLS
#define IMAGES_CACHE_SIZE_DEFAULT (1024 * 1024 * 80)
#define MIN_GLZ_WINDOW_SIZE_DEFAULT (1024 * 1024 * 12)
#define MAX_GLZ_WINDOW_SIZE_DEFAULT MIN((LZ_MAX_WINDOW_SIZE * 4), 1024 * 1024 * 64)
+#define WEBDAV_MAGIC_SIZE 16
struct _SpiceSessionPrivate {
char *host;
@@ -109,7 +110,7 @@ struct _SpiceSessionPrivate {
int glz_window_size;
uint32_t pci_ram_size;
uint32_t display_channels_count;
- guint8 uuid[16];
+ guint8 uuid[WEBDAV_MAGIC_SIZE];
gchar *name;
/* associated objects */
@@ -173,6 +174,13 @@ void spice_session_sync_playback_latency(SpiceSession *session);
const gchar* spice_session_get_shared_dir(SpiceSession *session);
void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir);
gboolean spice_session_get_audio_enabled(SpiceSession *session);
+gboolean spice_session_get_smartcard_enabled(SpiceSession *session);
+gboolean spice_session_get_usbredir_enabled(SpiceSession *session);
+
+const guint8* spice_session_get_webdav_magic(SpiceSession *session);
+guint spice_session_get_display_channels_count(SpiceSession *session);
+void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel);
+gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session);
G_END_DECLS
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 8b9655d..a2e79bb 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2199,6 +2199,14 @@ void spice_session_set_caches_hints(SpiceSession *session,
}
G_GNUC_INTERNAL
+guint spice_session_get_display_channels_count(SpiceSession *session)
+{
+ g_return_val_if_fail(session != NULL, 0);
+
+ return session->priv->display_channels_count;
+}
+
+G_GNUC_INTERNAL
void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16])
{
g_return_if_fail(SPICE_IS_SESSION(session));
@@ -2347,6 +2355,30 @@ gboolean spice_session_get_audio_enabled(SpiceSession *session)
return session->priv->audio;
}
+G_GNUC_INTERNAL
+gboolean spice_session_get_usbredir_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->usbredir;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_smartcard_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->smartcard;
+}
+
+G_GNUC_INTERNAL
+const guint8* spice_session_get_webdav_magic(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ return session->priv->webdav_magic;
+}
+
/**
* spice_session_is_for_migration:
* @session: a Spice session
@@ -2365,3 +2397,25 @@ gboolean spice_session_is_for_migration(SpiceSession *session)
return session->priv->for_migration;
}
+
+G_GNUC_INTERNAL
+void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+ g_return_if_fail(session->priv->cmain == NULL);
+
+ session->priv->cmain = channel;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+ g_return_val_if_fail(SPICE_IS_SESSION(mig_session), FALSE);
+ g_return_val_if_fail(session->priv->migration == NULL, FALSE);
+
+ session->priv->migration = mig_session;
+
+ return TRUE;
+}
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index dbd3d1a..f80b657 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -1627,7 +1627,7 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self,
g_return_val_if_fail(device != NULL, FALSE);
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
- if (!priv->session->priv->usbredir) {
+ if (!spice_session_get_usbredir_enabled(priv->session)) {
g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
_("USB redirection is disabled"));
return FALSE;
commit 74c3d288639a12838709ed2cd4881d386c3bc55b
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 18:19:50 2014 +0100
session: set session for migration when connecting
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 490d21c..bf7c204 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -2073,7 +2073,6 @@ static gboolean migrate_connect(gpointer data)
g_return_val_if_fail(c != NULL, FALSE);
g_return_val_if_fail(mig->session != NULL, FALSE);
- mig->session->priv->for_migration = true;
spice_session_set_migration_state(mig->session, SPICE_SESSION_MIGRATION_CONNECTING);
if ((c->peer_hdr.major_version == 1) &&
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index d1e1599..8b9655d 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2092,6 +2092,9 @@ void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigrat
SpiceSessionPrivate *s = session->priv;
+ if (state == SPICE_SESSION_MIGRATION_CONNECTING)
+ s->for_migration = true;
+
s->migration_state = state;
g_coroutine_object_notify(G_OBJECT(session), "migration-state");
}
commit 48373b267f750de0ef93cf569206b38597972e43
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 13:33:19 2014 +0100
session: rename migration_copy/for_migration
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 6d06ee3..490d21c 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -2073,7 +2073,7 @@ static gboolean migrate_connect(gpointer data)
g_return_val_if_fail(c != NULL, FALSE);
g_return_val_if_fail(mig->session != NULL, FALSE);
- mig->session->priv->migration_copy = true;
+ mig->session->priv->for_migration = true;
spice_session_set_migration_state(mig->session, SPICE_SESSION_MIGRATION_CONNECTING);
if ((c->peer_hdr.major_version == 1) &&
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 55e2ed2..6d8be8d 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -100,7 +100,7 @@ struct _SpiceSessionPrivate {
gboolean disconnecting;
gboolean migrate_wait_init;
guint after_main_init;
- gboolean migration_copy;
+ gboolean for_migration;
display_cache *images;
display_cache *palettes;
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 9a043b6..d1e1599 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2360,5 +2360,5 @@ gboolean spice_session_is_for_migration(SpiceSession *session)
{
g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
- return session->priv->migration_copy;
+ return session->priv->for_migration;
}
commit b6f25f9c667de83803ebb3ccb22b3f17c98dd6be
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:43:02 2014 +0100
smartcard: use spice_session_is_for_migration()
diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c
index 243a8ce..8588ae0 100644
--- a/gtk/channel-smartcard.c
+++ b/gtk/channel-smartcard.c
@@ -136,7 +136,7 @@ static void spice_smartcard_channel_constructed(GObject *object)
g_return_if_fail(s != NULL);
#ifdef USE_SMARTCARD
- if (!s->priv->migration_copy) {
+ if (!spice_session_is_for_migration(s)) {
SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(object);
SpiceSmartcardManager *manager = spice_smartcard_manager_get();
@@ -467,7 +467,7 @@ static void spice_smartcard_channel_up_cb(GObject *source_object,
static void spice_smartcard_channel_up(SpiceChannel *channel)
{
- if (spice_channel_get_session(SPICE_CHANNEL(channel))->priv->migration_copy)
+ if (spice_session_is_for_migration(spice_channel_get_session(channel)))
return;
spice_smartcard_manager_init_async(spice_channel_get_session(channel),
commit 2a72a2c665d4d6ecd9861377f7dfb6223cf31c47
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 13:52:08 2014 +0100
smartcard: do not initialize manager for migration session
The migration session is temporary and shouldn't interact with system.
diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c
index d27360c..243a8ce 100644
--- a/gtk/channel-smartcard.c
+++ b/gtk/channel-smartcard.c
@@ -452,23 +452,24 @@ static void spice_smartcard_channel_up_cb(GObject *source_object,
gpointer user_data)
{
SpiceChannel *channel = SPICE_CHANNEL(user_data);
+ GError *error = NULL;
g_return_if_fail(channel != NULL);
g_return_if_fail(SPICE_IS_SESSION(source_object));
- if (!spice_channel_get_session(SPICE_CHANNEL(channel))->priv->migration_copy) {
- GError *error = NULL;
+ spice_smartcard_manager_init_finish(SPICE_SESSION(source_object),
+ res, &error);
+ if (error)
+ g_warning("%s", error->message);
- spice_smartcard_manager_init_finish(SPICE_SESSION(source_object),
- res, &error);
- if (error)
- g_warning("%s", error->message);
- g_clear_error(&error);
- }
+ g_clear_error(&error);
}
static void spice_smartcard_channel_up(SpiceChannel *channel)
{
+ if (spice_channel_get_session(SPICE_CHANNEL(channel))->priv->migration_copy)
+ return;
+
spice_smartcard_manager_init_async(spice_channel_get_session(channel),
g_cancellable_new(),
spice_smartcard_channel_up_cb,
commit 5811432f49fde1ae22e21d94cce638116e0b4c5d
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:37:34 2014 +0100
Add spice_session_is_for_migration()
diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index caaa92c..141a32e 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -29,6 +29,7 @@ spice_session_get_channels
spice_session_get_read_only
spice_session_has_channel_type
spice_session_get_proxy_uri
+spice_session_is_for_migration
<SUBSECTION>
SpiceSessionMigration
SpiceSessionVerify
diff --git a/gtk/map-file b/gtk/map-file
index 3e9624f..d5a073f 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -86,6 +86,7 @@ spice_session_get_proxy_uri;
spice_session_get_read_only;
spice_session_get_type;
spice_session_has_channel_type;
+spice_session_is_for_migration;
spice_session_migration_get_type;
spice_session_new;
spice_session_open_fd;
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file
index 6ea8aeb..3a8da93 100644
--- a/gtk/spice-glib-sym-file
+++ b/gtk/spice-glib-sym-file
@@ -63,6 +63,7 @@ spice_session_get_proxy_uri
spice_session_get_read_only
spice_session_get_type
spice_session_has_channel_type
+spice_session_is_for_migration
spice_session_migration_get_type
spice_session_new
spice_session_open_fd
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 911bde2..9a043b6 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2343,3 +2343,22 @@ gboolean spice_session_get_audio_enabled(SpiceSession *session)
return session->priv->audio;
}
+
+/**
+ * spice_session_is_for_migration:
+ * @session: a Spice session
+ *
+ * During seamless migration, channels may be created to establish a
+ * connection with the target, but they are temporary and should only
+ * handle migration steps. In order to avoid other interactions with
+ * the client, channels should check this value.
+ *
+ * Returns: %TRUE if the session is a copy created during migration
+ * Since: 0.27
+ **/
+gboolean spice_session_is_for_migration(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->migration_copy;
+}
diff --git a/gtk/spice-session.h b/gtk/spice-session.h
index 4043a64..a79894f 100644
--- a/gtk/spice-session.h
+++ b/gtk/spice-session.h
@@ -96,6 +96,7 @@ GList *spice_session_get_channels(SpiceSession *session);
gboolean spice_session_has_channel_type(SpiceSession *session, gint type);
gboolean spice_session_get_read_only(SpiceSession *session);
SpiceURI *spice_session_get_proxy_uri(SpiceSession *session);
+gboolean spice_session_is_for_migration(SpiceSession *session);
G_END_DECLS
commit 2fad13d010c395b23d865c03f8045cd654c35dad
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Tue Nov 25 11:33:55 2014 +0100
session: protect internal functions against invalid args
Make sure calling an internal session function returns with an error
when called with a NULL pointer. This will help channel code when
it is removed from session before being destructed.
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 948c238..911bde2 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1226,6 +1226,8 @@ SpiceSession *spice_session_new(void)
G_GNUC_INTERNAL
SpiceSession *spice_session_new_from_session(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
SpiceSession *copy;
SpiceSessionPrivate *c;
@@ -1294,7 +1296,6 @@ gboolean spice_session_connect(SpiceSession *session)
SpiceSessionPrivate *s;
g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
- g_return_val_if_fail(session->priv != NULL, FALSE);
s = session->priv;
@@ -1329,7 +1330,6 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd)
SpiceSessionPrivate *s;
g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
- g_return_val_if_fail(session->priv != NULL, FALSE);
g_return_val_if_fail(fd >= -1, FALSE);
s = session->priv;
@@ -1349,9 +1349,10 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd)
G_GNUC_INTERNAL
gboolean spice_session_get_client_provided_socket(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, FALSE);
return s->client_provided_sockets;
}
@@ -1366,11 +1367,12 @@ static void cache_clear_all(SpiceSession *self)
G_GNUC_INTERNAL
void spice_session_switching_disconnect(SpiceSession *self)
{
+ g_return_if_fail(SPICE_IS_SESSION(self));
+
SpiceSessionPrivate *s = self->priv;
struct channel *item;
RingItem *ring, *next;
- g_return_if_fail(s != NULL);
g_return_if_fail(s->cmain != NULL);
/* disconnect/destroy all but main channel */
@@ -1391,6 +1393,8 @@ G_GNUC_INTERNAL
void spice_session_start_migrating(SpiceSession *session,
gboolean full_migration)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
SpiceSessionPrivate *m;
gchar *tmp;
@@ -1426,12 +1430,12 @@ void spice_session_start_migrating(SpiceSession *session,
G_GNUC_INTERNAL
SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint type)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
RingItem *ring, *next;
SpiceSessionPrivate *s = session->priv;
struct channel *c;
- g_return_val_if_fail(s != NULL, NULL);
-
for (ring = ring_get_head(&s->channels);
ring != NULL; ring = next) {
next = ring_next(&s->channels, ring);
@@ -1453,12 +1457,12 @@ SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint
G_GNUC_INTERNAL
void spice_session_abort_migration(SpiceSession *session)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
RingItem *ring, *next;
struct channel *c;
- g_return_if_fail(s != NULL);
-
if (s->migration == NULL) {
SPICE_DEBUG("no migration in progress");
return;
@@ -1502,11 +1506,12 @@ end:
G_GNUC_INTERNAL
void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
SpiceChannel *c;
gint id, type;
- g_return_if_fail(s != NULL);
g_return_if_fail(s->migration != NULL);
g_return_if_fail(SPICE_IS_CHANNEL(channel));
@@ -1556,6 +1561,8 @@ static gboolean after_main_init(gpointer data)
G_GNUC_INTERNAL
gboolean spice_session_migrate_after_main_init(SpiceSession *self)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(self), FALSE);
+
SpiceSessionPrivate *s = self->priv;
if (!s->migrate_wait_init)
@@ -1574,6 +1581,8 @@ gboolean spice_session_migrate_after_main_init(SpiceSession *self)
G_GNUC_INTERNAL
void spice_session_migrate_end(SpiceSession *self)
{
+ g_return_if_fail(SPICE_IS_SESSION(self));
+
SpiceSessionPrivate *s = self->priv;
SpiceMsgOut *out;
GList *l;
@@ -1853,6 +1862,8 @@ G_GNUC_INTERNAL
GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
gboolean *use_tls, GError **error)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
SpiceChannelPrivate *c = channel->priv;
spice_open_host open_host = { 0, };
@@ -1905,11 +1916,12 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC
G_GNUC_INTERNAL
void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
SpiceSessionPrivate *s = session->priv;
struct channel *item;
- g_return_if_fail(s != NULL);
- g_return_if_fail(channel != NULL);
item = g_new0(struct channel, 1);
item->channel = channel;
@@ -1939,13 +1951,13 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
G_GNUC_INTERNAL
void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
SpiceSessionPrivate *s = session->priv;
struct channel *item = NULL;
RingItem *ring;
- g_return_if_fail(s != NULL);
- g_return_if_fail(channel != NULL);
-
if (s->migration_left)
s->migration_left = g_list_remove(s->migration_left, channel);
@@ -1972,9 +1984,9 @@ void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
G_GNUC_INTERNAL
void spice_session_set_connection_id(SpiceSession *session, int id)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_if_fail(SPICE_IS_SESSION(session));
- g_return_if_fail(s != NULL);
+ SpiceSessionPrivate *s = session->priv;
s->connection_id = id;
}
@@ -1982,9 +1994,9 @@ void spice_session_set_connection_id(SpiceSession *session, int id)
G_GNUC_INTERNAL
int spice_session_get_connection_id(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_val_if_fail(SPICE_IS_SESSION(session), -1);
- g_return_val_if_fail(s != NULL, -1);
+ SpiceSessionPrivate *s = session->priv;
return s->connection_id;
}
@@ -1992,9 +2004,9 @@ int spice_session_get_connection_id(SpiceSession *session)
G_GNUC_INTERNAL
guint32 spice_session_get_mm_time(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
- g_return_val_if_fail(s != NULL, 0);
+ SpiceSessionPrivate *s = session->priv;
/* FIXME: we may want to estimate the drift of clocks, and well,
do something better than this trivial approach */
@@ -2006,11 +2018,11 @@ guint32 spice_session_get_mm_time(SpiceSession *session)
G_GNUC_INTERNAL
void spice_session_set_mm_time(SpiceSession *session, guint32 time)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
guint32 old_time;
- g_return_if_fail(s != NULL);
-
old_time = spice_session_get_mm_time(session);
s->mm_time = time;
@@ -2029,7 +2041,7 @@ void spice_session_set_port(SpiceSession *session, int port, gboolean tls)
const char *prop = tls ? "tls-port" : "port";
char *tmp;
- g_return_if_fail(session != NULL);
+ g_return_if_fail(SPICE_IS_SESSION(session));
/* old spicec client doesn't accept port == 0, see Migrate::start */
tmp = port > 0 ? g_strdup_printf("%d", port) : NULL;
@@ -2040,12 +2052,12 @@ void spice_session_set_port(SpiceSession *session, int port, gboolean tls)
G_GNUC_INTERNAL
void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *size)
{
- SpiceSessionPrivate *s = session->priv;
-
- g_return_if_fail(s != NULL);
+ g_return_if_fail(SPICE_IS_SESSION(session));
g_return_if_fail(pubkey != NULL);
g_return_if_fail(size != NULL);
+ SpiceSessionPrivate *s = session->priv;
+
*pubkey = s->pubkey ? s->pubkey->data : NULL;
*size = s->pubkey ? s->pubkey->len : 0;
}
@@ -2053,12 +2065,12 @@ void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *siz
G_GNUC_INTERNAL
void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size)
{
- SpiceSessionPrivate *s = session->priv;
-
- g_return_if_fail(s != NULL);
+ g_return_if_fail(SPICE_IS_SESSION(session));
g_return_if_fail(ca != NULL);
g_return_if_fail(size != NULL);
+ SpiceSessionPrivate *s = session->priv;
+
*ca = s->ca ? s->ca->data : NULL;
*size = s->ca ? s->ca->len : 0;
}
@@ -2066,18 +2078,20 @@ void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size)
G_GNUC_INTERNAL
guint spice_session_get_verify(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, 0);
return s->verify;
}
G_GNUC_INTERNAL
void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigration state)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
- g_return_if_fail(s != NULL);
s->migration_state = state;
g_coroutine_object_notify(G_OBJECT(session), "migration-state");
}
@@ -2085,54 +2099,60 @@ void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigrat
G_GNUC_INTERNAL
const gchar* spice_session_get_username(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->username;
}
G_GNUC_INTERNAL
const gchar* spice_session_get_password(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->password;
}
G_GNUC_INTERNAL
const gchar* spice_session_get_host(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->host;
}
G_GNUC_INTERNAL
const gchar* spice_session_get_cert_subject(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->cert_subject;
}
G_GNUC_INTERNAL
const gchar* spice_session_get_ciphers(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->ciphers;
}
G_GNUC_INTERNAL
const gchar* spice_session_get_ca_file(SpiceSession *session)
{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
SpiceSessionPrivate *s = session->priv;
- g_return_val_if_fail(s != NULL, NULL);
return s->ca_file;
}
@@ -2141,9 +2161,9 @@ void spice_session_get_caches(SpiceSession *session,
display_cache **images,
SpiceGlzDecoderWindow **glz_window)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_if_fail(SPICE_IS_SESSION(session));
- g_return_if_fail(s != NULL);
+ SpiceSessionPrivate *s = session->priv;
if (images)
*images = s->images;
@@ -2156,9 +2176,9 @@ void spice_session_set_caches_hints(SpiceSession *session,
uint32_t pci_ram_size,
uint32_t display_channels_count)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_if_fail(SPICE_IS_SESSION(session));
- g_return_if_fail(s != NULL);
+ SpiceSessionPrivate *s = session->priv;
s->pci_ram_size = pci_ram_size;
s->display_channels_count = display_channels_count;
@@ -2178,9 +2198,10 @@ void spice_session_set_caches_hints(SpiceSession *session,
G_GNUC_INTERNAL
void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16])
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
- g_return_if_fail(s != NULL);
memcpy(s->uuid, uuid, sizeof(s->uuid));
g_coroutine_object_notify(G_OBJECT(session), "uuid");
@@ -2189,9 +2210,10 @@ void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16])
G_GNUC_INTERNAL
void spice_session_set_name(SpiceSession *session, const gchar *name)
{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
SpiceSessionPrivate *s = session->priv;
- g_return_if_fail(s != NULL);
g_free(s->name);
s->name = g_strdup(name);
@@ -2201,9 +2223,9 @@ void spice_session_set_name(SpiceSession *session, const gchar *name)
G_GNUC_INTERNAL
void spice_session_sync_playback_latency(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_if_fail(SPICE_IS_SESSION(session));
- g_return_if_fail(s != NULL);
+ SpiceSessionPrivate *s = session->priv;
if (s->playback_channel &&
spice_playback_channel_is_active(s->playback_channel)) {
@@ -2216,9 +2238,9 @@ void spice_session_sync_playback_latency(SpiceSession *session)
G_GNUC_INTERNAL
gboolean spice_session_is_playback_active(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
- g_return_val_if_fail(s != NULL, FALSE);
+ SpiceSessionPrivate *s = session->priv;
return (s->playback_channel &&
spice_playback_channel_is_active(s->playback_channel));
@@ -2227,9 +2249,9 @@ gboolean spice_session_is_playback_active(SpiceSession *session)
G_GNUC_INTERNAL
guint32 spice_session_get_playback_latency(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
- g_return_val_if_fail(s != NULL, 0);
+ SpiceSessionPrivate *s = session->priv;
if (s->playback_channel &&
spice_playback_channel_is_active(s->playback_channel)) {
@@ -2243,9 +2265,9 @@ guint32 spice_session_get_playback_latency(SpiceSession *session)
G_GNUC_INTERNAL
const gchar* spice_session_get_shared_dir(SpiceSession *session)
{
- SpiceSessionPrivate *s = session->priv;
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
- g_return_val_if_fail(s != NULL, NULL);
+ SpiceSessionPrivate *s = session->priv;
return s->shared_dir;
}
@@ -2253,10 +2275,10 @@ const gchar* spice_session_get_shared_dir(SpiceSession *session)
G_GNUC_INTERNAL
void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir)
{
- SpiceSessionPrivate *s = session->priv;
-
+ g_return_if_fail(SPICE_IS_SESSION(session));
g_return_if_fail(dir != NULL);
- g_return_if_fail(s != NULL);
+
+ SpiceSessionPrivate *s = session->priv;
g_free(s->shared_dir);
s->shared_dir = g_strdup(dir);
commit acf99be38c84e0eec4d87cfb1b207087f43a9460
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 13:26:38 2014 +0100
audio: move spice_audio_get() to session
diff --git a/gtk/spice-audio.c b/gtk/spice-audio.c
index ce303f1..7754736 100644
--- a/gtk/spice-audio.c
+++ b/gtk/spice-audio.c
@@ -230,34 +230,3 @@ SpiceAudio *spice_audio_new(SpiceSession *session, GMainContext *context,
return self;
}
-
-/**
- * spice_audio_get:
- * @session: the #SpiceSession to connect to
- * @context: (allow-none): a #GMainContext to attach to (or %NULL for default).
- *
- * Gets the #SpiceAudio associated with the passed in #SpiceSession.
- * A new #SpiceAudio instance will be created the first time this
- * function is called for a certain #SpiceSession.
- *
- * Note that this function returns a weak reference, which should not be used
- * after the #SpiceSession itself has been unref-ed by the caller.
- *
- * Returns: (transfer none): a weak reference to a #SpiceAudio
- * instance or %NULL if failed.
- **/
-SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context)
-{
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- SpiceAudio *self;
-
- g_static_mutex_lock(&mutex);
- self = session->priv->audio_manager;
- if (self == NULL) {
- self = spice_audio_new(session, context, NULL);
- session->priv->audio_manager = self;
- }
- g_static_mutex_unlock(&mutex);
-
- return self;
-}
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index f729ae0..948c238 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -32,6 +32,7 @@
#include "wocky-http-proxy.h"
#include "spice-uri-priv.h"
#include "channel-playback-priv.h"
+#include "spice-audio.h"
struct channel {
SpiceChannel *channel;
@@ -2280,6 +2281,39 @@ SpiceURI *spice_session_get_proxy_uri(SpiceSession *session)
return s->proxy;
}
+/**
+ * spice_audio_get:
+ * @session: the #SpiceSession to connect to
+ * @context: (allow-none): a #GMainContext to attach to (or %NULL for default).
+ *
+ * Gets the #SpiceAudio associated with the passed in #SpiceSession.
+ * A new #SpiceAudio instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to a #SpiceAudio
+ * instance or %NULL if failed.
+ **/
+SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context)
+{
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+ SpiceAudio *self;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ g_static_mutex_lock(&mutex);
+ self = session->priv->audio_manager;
+ if (self == NULL) {
+ self = spice_audio_new(session, context, NULL);
+ session->priv->audio_manager = self;
+ }
+ g_static_mutex_unlock(&mutex);
+
+ return self;
+}
+
G_GNUC_INTERNAL
gboolean spice_session_get_audio_enabled(SpiceSession *session)
{
commit d29a23a82979bef25e8104b13f925fecc0961ee4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Wed Nov 26 13:25:51 2014 +0100
audio: add accessor to check if audio is enabled
diff --git a/gtk/spice-audio.c b/gtk/spice-audio.c
index 638f667..ce303f1 100644
--- a/gtk/spice-audio.c
+++ b/gtk/spice-audio.c
@@ -166,17 +166,18 @@ static void connect_channel(SpiceAudio *self, SpiceChannel *channel)
static void update_audio_channels(SpiceAudio *self, SpiceSession *session)
{
- if (session->priv->audio) {
- GList *list, *tmp;
-
- list = spice_session_get_channels(session);
- for (tmp = g_list_first(list); tmp != NULL; tmp = g_list_next(tmp)) {
- connect_channel(self, tmp->data);
- }
- g_list_free(list);
- } else {
+ GList *list, *tmp;
+
+ if (!spice_session_get_audio_enabled(session)) {
g_debug("FIXME: disconnect audio channels");
+ return;
+ }
+
+ list = spice_session_get_channels(session);
+ for (tmp = g_list_first(list); tmp != NULL; tmp = g_list_next(tmp)) {
+ connect_channel(self, tmp->data);
}
+ g_list_free(list);
}
static void channel_new(SpiceSession *session, SpiceChannel *channel, SpiceAudio *self)
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 8e102e0..55e2ed2 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -172,6 +172,7 @@ guint32 spice_session_get_playback_latency(SpiceSession *session);
void spice_session_sync_playback_latency(SpiceSession *session);
const gchar* spice_session_get_shared_dir(SpiceSession *session);
void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir);
+gboolean spice_session_get_audio_enabled(SpiceSession *session);
G_END_DECLS
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index c44a3e1..f729ae0 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2279,3 +2279,11 @@ SpiceURI *spice_session_get_proxy_uri(SpiceSession *session)
return s->proxy;
}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_audio_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->audio;
+}
More information about the Spice-commits
mailing list