[Spice-commits] 3 commits - common/messages.h gtk/channel-main.c gtk/spice-channel.c gtk/spice-session.c gtk/spice-session-priv.h gtk/spice-util.c gtk/spice-util-priv.h python_modules/demarshal.py spice.proto spice-protocol
Marc-André Lureau
elmarco at kemper.freedesktop.org
Tue Mar 6 06:42:55 PST 2012
common/messages.h | 9 +++
gtk/channel-main.c | 27 +++++++++++
gtk/spice-channel.c | 102 +++++++++++++++++++-------------------------
gtk/spice-session-priv.h | 5 +-
gtk/spice-session.c | 63 +++++++++++++++++++++++++++
gtk/spice-util-priv.h | 3 +
gtk/spice-util.c | 11 ++++
python_modules/demarshal.py | 2
spice-protocol | 2
spice.proto | 9 +++
10 files changed, 173 insertions(+), 60 deletions(-)
New commits:
commit 8eda31dc5b75c7f07787d823849503425cfee0df
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Mon Mar 5 18:01:21 2012 +0100
Fix semi-seamless migration handling
SPICE_MSGC_MAIN_MIGRATE_END was dropped because the main channel was
xmit_queue_blocked. When we swap the channels, we should also swap
xmit_queue.
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index d0a287b..79775f9 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2578,49 +2578,32 @@ void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap)
g_return_if_fail(s->session != NULL);
g_return_if_fail(s->sock != NULL);
- {
- GSocket *sock = c->sock;
- SSL_CTX *ctx = c->ctx;
- SSL *ssl = c->ssl;
- SpiceOpenSSLVerify *sslverify = c->sslverify;
- uint64_t in_serial = c->in_serial;
- uint64_t out_serial = c->out_serial;
- gboolean use_mini_header = c->use_mini_header;
-
- c->sock = s->sock;
- c->ctx = s->ctx;
- c->ssl = s->ssl;
- c->sslverify = s->sslverify;
- c->in_serial = s->in_serial;
- c->out_serial = s->out_serial;
- c->use_mini_header = s->use_mini_header;
-
- s->sock = sock;
- s->ctx = ctx;
- s->ssl = ssl;
- s->sslverify = sslverify;
- s->in_serial = in_serial;
- s->out_serial = out_serial;
- s->use_mini_header = use_mini_header;
- }
-
+#define SWAP(Field) ({ \
+ typeof (c->Field) Field = c->Field; \
+ c->Field = s->Field; \
+ s->Field = Field; \
+})
+
+ /* TODO: split channel in 2 objects: a controller and a swappable
+ state object */
+ SWAP(sock);
+ SWAP(ctx);
+ SWAP(ssl);
+ SWAP(sslverify);
+ SWAP(in_serial);
+ SWAP(out_serial);
+ SWAP(use_mini_header);
+ SWAP(xmit_queue);
+ SWAP(xmit_queue_blocked);
+ SWAP(caps);
+ SWAP(common_caps);
+ SWAP(remote_caps);
+ SWAP(remote_common_caps);
#if HAVE_SASL
- {
- sasl_conn_t *sasl_conn = c->sasl_conn;
- const char *sasl_decoded = c->sasl_decoded;
- unsigned int sasl_decoded_length = c->sasl_decoded_length;
- unsigned int sasl_decoded_offset = c->sasl_decoded_offset;
-
- c->sasl_conn = s->sasl_conn;
- c->sasl_decoded = s->sasl_decoded;
- c->sasl_decoded_length = s->sasl_decoded_length;
- c->sasl_decoded_offset = s->sasl_decoded_offset;
-
- s->sasl_conn = sasl_conn;
- s->sasl_decoded = sasl_decoded;
- s->sasl_decoded_length = sasl_decoded_length;
- s->sasl_decoded_offset = sasl_decoded_offset;
- }
+ SWAP(sasl_conn);
+ SWAP(sasl_decoded);
+ SWAP(sasl_decoded_length);
+ SWAP(sasl_decoded_offset);
#endif
}
commit 73a28efdbadade681a5a6ae4f639315083a9c8ab
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Mon Mar 5 17:58:31 2012 +0100
Warn if a message is dropped (before connection or after reset)
Since c2ba62666beaee526e1b4288f9bd66976ce780ef messages can be ignored
when a channel is reset. A warning can help explain why some messages
are dropped.
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index c1c145a..d0a287b 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -678,26 +678,31 @@ static gboolean spice_channel_idle_wakeup(gpointer user_data)
G_GNUC_INTERNAL
void spice_msg_out_send(SpiceMsgOut *out)
{
+ gboolean was_empty;
+
g_return_if_fail(out != NULL);
g_return_if_fail(out->channel != NULL);
g_static_mutex_lock(&out->channel->priv->xmit_queue_lock);
- if (!out->channel->priv->xmit_queue_blocked) {
- gboolean was_empty;
-
- was_empty = g_queue_is_empty(&out->channel->priv->xmit_queue);
- g_queue_push_tail(&out->channel->priv->xmit_queue, out);
-
- /* One wakeup is enough to empty the entire queue -> only do a wakeup
- if the queue was empty, and there isn't one pending already. */
- if (was_empty && !out->channel->priv->xmit_queue_wakeup_id) {
- out->channel->priv->xmit_queue_wakeup_id =
- /* Use g_timeout_add_full so that can specify the priority */
- g_timeout_add_full(G_PRIORITY_HIGH, 0,
- spice_channel_idle_wakeup,
- out->channel, NULL);
- }
+ if (out->channel->priv->xmit_queue_blocked) {
+ g_warning("message queue is blocked, dropping message");
+ goto end;
+ }
+
+ was_empty = g_queue_is_empty(&out->channel->priv->xmit_queue);
+ g_queue_push_tail(&out->channel->priv->xmit_queue, out);
+
+ /* One wakeup is enough to empty the entire queue -> only do a wakeup
+ if the queue was empty, and there isn't one pending already. */
+ if (was_empty && !out->channel->priv->xmit_queue_wakeup_id) {
+ out->channel->priv->xmit_queue_wakeup_id =
+ /* Use g_timeout_add_full so that can specify the priority */
+ g_timeout_add_full(G_PRIORITY_HIGH, 0,
+ spice_channel_idle_wakeup,
+ out->channel, NULL);
}
+
+end:
g_static_mutex_unlock(&out->channel->priv->xmit_queue_lock);
}
commit ec2e3a3c01837bb72bf3e143522aa87d532ba9af
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Thu Mar 1 14:08:48 2012 +0100
Support name & uuid
Allows a client to identify the server it is connected to.
diff --git a/common/messages.h b/common/messages.h
index 4a69c35..01689cd 100644
--- a/common/messages.h
+++ b/common/messages.h
@@ -156,6 +156,15 @@ typedef struct SpiceMsgChannels {
SpiceChannelId channels[0];
} SpiceMsgChannels;
+typedef struct SpiceMsgMainName {
+ uint32_t name_len;
+ uint8_t name[0];
+} SpiceMsgMainName;
+
+typedef struct SpiceMsgMainUuid {
+ uint8_t uuid[16];
+} SpiceMsgMainUuid;
+
typedef struct SpiceMsgMainMouseMode {
uint32_t supported_modes;
uint32_t current_mode;
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 0689368..dbe78d9 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -20,6 +20,7 @@
#include "spice-common.h"
#include "spice-marshal.h"
+#include "spice-util-priv.h"
#include "spice-channel-priv.h"
#include "spice-session-priv.h"
@@ -161,6 +162,7 @@ static void spice_main_channel_init(SpiceMainChannel *channel)
c->agent_msg_queue = g_queue_new();
spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_NAME_AND_UUID);
}
static void spice_main_get_property(GObject *object,
@@ -1143,6 +1145,29 @@ static void main_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
}
/* coroutine context */
+static void main_handle_name(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainName *name = spice_msg_in_parsed(in);
+ SpiceSession *session = spice_channel_get_session(channel);
+
+ SPICE_DEBUG("server name: %s", name->name);
+ spice_session_set_name(session, (const gchar *)name->name);
+}
+
+/* coroutine context */
+static void main_handle_uuid(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainUuid *uuid = spice_msg_in_parsed(in);
+ SpiceSession *session = spice_channel_get_session(channel);
+ gchar *uuid_str = spice_uuid_to_string(uuid->uuid);
+
+ SPICE_DEBUG("server uuid: %s", uuid_str);
+ spice_session_set_uuid(session, uuid->uuid);
+
+ g_free(uuid_str);
+}
+
+/* coroutine context */
static void main_handle_mm_time(SpiceChannel *channel, SpiceMsgIn *in)
{
SpiceSession *session;
@@ -1669,6 +1694,8 @@ static void main_handle_migrate_cancel(SpiceChannel *channel,
static const spice_msg_handler main_handlers[] = {
[ SPICE_MSG_MAIN_INIT ] = main_handle_init,
+ [ SPICE_MSG_MAIN_NAME ] = main_handle_name,
+ [ SPICE_MSG_MAIN_UUID ] = main_handle_uuid,
[ SPICE_MSG_MAIN_CHANNELS_LIST ] = main_handle_channels_list,
[ SPICE_MSG_MAIN_MOUSE_MODE ] = main_handle_mouse_mode,
[ SPICE_MSG_MAIN_MULTI_MEDIA_TIME ] = main_handle_mm_time,
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index a814cfe..5cef264 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -92,7 +92,8 @@ struct _SpiceSessionPrivate {
int glz_window_size;
uint32_t pci_ram_size;
uint32_t display_channels_count;
-
+ guint8 uuid[16];
+ gchar *name;
/* associated objects */
SpiceAudio *audio_manager;
@@ -141,6 +142,8 @@ void spice_session_images_clear(SpiceSession *session);
void spice_session_migrate_end(SpiceSession *session);
gboolean spice_session_migrate_after_main_init(SpiceSession *session);
SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint type);
+void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16]);
+void spice_session_set_name(SpiceSession *session, const gchar *name);
G_END_DECLS
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 991fb60..420601d 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -103,6 +103,8 @@ enum {
PROP_READ_ONLY,
PROP_CACHE_SIZE,
PROP_GLZ_WINDOW_SIZE,
+ PROP_UUID,
+ PROP_NAME,
};
/* signals */
@@ -416,6 +418,12 @@ static void spice_session_get_property(GObject *gobject,
case PROP_GLZ_WINDOW_SIZE:
g_value_set_int(value, s->glz_window_size);
break;
+ case PROP_NAME:
+ g_value_set_string(value, s->name);
+ break;
+ case PROP_UUID:
+ g_value_set_pointer(value, s->uuid);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
@@ -957,6 +965,33 @@ static void spice_session_class_init(SpiceSessionClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ /**
+ * SpiceSession:name:
+ *
+ * Spice server name.
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_NAME,
+ g_param_spec_string("name",
+ "Name",
+ "Spice server name",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:uuid:
+ *
+ * Spice server uuid.
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_UUID,
+ g_param_spec_pointer("uuid",
+ "UUID",
+ "Spice server uuid",
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
g_type_class_add_private(klass, sizeof(SpiceSessionPrivate));
}
@@ -1346,6 +1381,11 @@ void spice_session_disconnect(SpiceSession *session)
}
s->connection_id = 0;
+
+ g_free(s->name);
+ s->name = NULL;
+ memset(s->uuid, 0, sizeof(s->uuid));
+
/* we leave disconnecting = TRUE, so that spice_channel_destroy()
is not called multiple times on channels that are in pending
destroy state. */
@@ -1740,3 +1780,26 @@ void spice_session_set_caches_hints(SpiceSession *session,
s->glz_window_size = MAX(MIN_GLZ_WINDOW_SIZE_DEFAULT, s->glz_window_size);
}
}
+
+G_GNUC_INTERNAL
+void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16])
+{
+ SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+
+ g_return_if_fail(s != NULL);
+ memcpy(s->uuid, uuid, sizeof(s->uuid));
+
+ g_object_notify(G_OBJECT(session), "uuid");
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_name(SpiceSession *session, const gchar *name)
+{
+ SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+
+ g_return_if_fail(s != NULL);
+ g_free(s->name);
+ s->name = g_strdup(name);
+
+ g_object_notify(G_OBJECT(session), "name");
+}
diff --git a/gtk/spice-util-priv.h b/gtk/spice-util-priv.h
index 90b437c..ee70f64 100644
--- a/gtk/spice-util-priv.h
+++ b/gtk/spice-util-priv.h
@@ -22,7 +22,10 @@
G_BEGIN_DECLS
+#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+
gboolean spice_strv_contains(const GStrv strv, const gchar *str);
+gchar* spice_uuid_to_string(const guint8 uuid[16]);
G_END_DECLS
diff --git a/gtk/spice-util.c b/gtk/spice-util.c
index f2f30e8..65454ef 100644
--- a/gtk/spice-util.c
+++ b/gtk/spice-util.c
@@ -20,6 +20,7 @@
# include "config.h"
#endif
#include <glib-object.h>
+#include "spice-util-priv.h"
#include "spice-util.h"
/**
@@ -76,6 +77,16 @@ gboolean spice_strv_contains(const GStrv strv, const gchar *str)
return FALSE;
}
+G_GNUC_INTERNAL
+gchar* spice_uuid_to_string(const guint8 uuid[16])
+{
+ return g_strdup_printf(UUID_FMT, uuid[0], uuid[1],
+ uuid[2], uuid[3], uuid[4], uuid[5],
+ uuid[6], uuid[7], uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13],
+ uuid[14], uuid[15]);
+}
+
typedef struct {
GObject *instance;
GObject *observer;
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 9847fb4..c999bd3 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -664,7 +664,7 @@ def read_array_len(writer, prefix, array, dest, scope, is_ptr):
nelements = "%s__array__nelements" % prefix
else:
nelements = "%s__nelements" % prefix
- if dest.is_toplevel():
+ if dest.is_toplevel() and scope.variable_defined(nelements):
return nelements # Already there for toplevel, need not recalculate
element_type = array.element_type
scope.variable_def("uint32_t", nelements)
diff --git a/spice-protocol b/spice-protocol
index d5edafd..1a3b563 160000
--- a/spice-protocol
+++ b/spice-protocol
@@ -1 +1 @@
-Subproject commit d5edafd28ab762b1b5f663aec449d3e3743f1184
+Subproject commit 1a3b563171ad81f6b44f6e5ef6f244b169419704
diff --git a/spice.proto b/spice.proto
index 28a9435..da01a94 100644
--- a/spice.proto
+++ b/spice.proto
@@ -221,6 +221,15 @@ channel MainChannel : BaseChannel {
Empty migrate_end;
+ message {
+ uint32 name_len;
+ uint8 name[name_len];
+ } name;
+
+ message {
+ uint8 uuid[16];
+ } uuid;
+
client:
message {
uint64 cache_size;
More information about the Spice-commits
mailing list