[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