[Spice-devel] [spice-server 5/5] channel-client: Implement red_channel_client_get_pipe_item_name

Christophe Fergeau cfergeau at redhat.com
Thu Oct 12 10:13:26 UTC 2017


Given a RedPipeItem, this returns a string corresponding to its type,
which is useful while debugging to get a better feel of what's going on.

This is achieved by introducing a new
RedChannelClientClass::red_pipe_item_type member, which is then used
together with the enum data generated by glib-mkenums to turn an enum
int value into a string.
---
 server/common-graphics-channel.c  |  2 ++
 server/cursor-channel-client.c    |  2 ++
 server/dcc.c                      |  2 ++
 server/inputs-channel-client.c    |  2 ++
 server/main-channel-client.c      |  2 ++
 server/red-channel-client.c       | 39 +++++++++++++++++++++++++++++++++++++++
 server/red-channel-client.h       |  2 ++
 server/smartcard-channel-client.c |  2 ++
 server/spicevmc.c                 | 27 ++++++++++++++++++++++++++-
 9 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/server/common-graphics-channel.c b/server/common-graphics-channel.c
index 0cbc2762c..c36f2966f 100644
--- a/server/common-graphics-channel.c
+++ b/server/common-graphics-channel.c
@@ -23,6 +23,7 @@
 #include "common-graphics-channel.h"
 #include "dcc.h"
 #include "red-client.h"
+#include "red-pipe-item-enums.h"
 
 #define CHANNEL_RECEIVE_BUF_SIZE 1024
 
@@ -134,6 +135,7 @@ common_graphics_channel_client_class_init(CommonGraphicsChannelClientClass *klas
 
     g_type_class_add_private(klass, sizeof(CommonGraphicsChannelClientPrivate));
 
+    client_class->red_pipe_item_type = COMMON_GRAPHICS_CHANNEL_PIPE_ITEM_TYPE;
     client_class->config_socket = common_channel_client_config_socket;
     client_class->alloc_recv_buf = common_alloc_recv_buf;
     client_class->release_recv_buf = common_release_recv_buf;
diff --git a/server/cursor-channel-client.c b/server/cursor-channel-client.c
index 42ab5d763..e3a452cac 100644
--- a/server/cursor-channel-client.c
+++ b/server/cursor-channel-client.c
@@ -23,6 +23,7 @@
 
 #include "common-graphics-channel.h"
 #include "red-channel-client.h"
+#include "red-pipe-item-enums.h"
 #include "cache-item.h"
 #include "cursor-channel.h"
 #include "cursor-channel-client.h"
@@ -57,6 +58,7 @@ cursor_channel_client_class_init(CursorChannelClientClass *klass)
 
     g_type_class_add_private(klass, sizeof(CursorChannelClientPrivate));
 
+    client_class->red_pipe_item_type = CURSOR_CHANNEL_PIPE_ITEM_TYPE;
     client_class->on_disconnect = cursor_channel_client_on_disconnect;
 }
 
diff --git a/server/dcc.c b/server/dcc.c
index 90684e17c..6360d0b8e 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -24,6 +24,7 @@
 #include "display-channel-private.h"
 #include "red-client.h"
 #include "main-channel-client.h"
+#include "red-pipe-item-enums.h"
 #include "spice-server-enums.h"
 #include "glib-compat.h"
 
@@ -133,6 +134,7 @@ display_channel_client_class_init(DisplayChannelClientClass *klass)
     object_class->constructed = display_channel_client_constructed;
     object_class->finalize = display_channel_client_finalize;
 
+    client_class->red_pipe_item_type = DISPLAY_CHANNEL_PIPE_ITEM_TYPE;
     client_class->config_socket = dcc_config_socket;
     client_class->on_disconnect = dcc_on_disconnect;
 
diff --git a/server/inputs-channel-client.c b/server/inputs-channel-client.c
index c9c88da23..35fab1051 100644
--- a/server/inputs-channel-client.c
+++ b/server/inputs-channel-client.c
@@ -21,6 +21,7 @@
 #include "inputs-channel-client.h"
 #include "migration-protocol.h"
 #include "red-channel-client.h"
+#include "red-pipe-item-enums.h"
 
 G_DEFINE_TYPE(InputsChannelClient, inputs_channel_client, RED_TYPE_CHANNEL_CLIENT)
 
@@ -78,6 +79,7 @@ inputs_channel_client_class_init(InputsChannelClientClass *klass)
 
     g_type_class_add_private(klass, sizeof(InputsChannelClientPrivate));
 
+    client_class->red_pipe_item_type = INPUT_CHANNEL_PIPE_ITEM_TYPE;
     client_class->alloc_recv_buf = inputs_channel_client_alloc_msg_rcv_buf;
     client_class->release_recv_buf = inputs_channel_client_release_msg_rcv_buf;
     client_class->on_disconnect = inputs_channel_client_on_disconnect;
diff --git a/server/main-channel-client.c b/server/main-channel-client.c
index bdcc1e825..61700bb51 100644
--- a/server/main-channel-client.c
+++ b/server/main-channel-client.c
@@ -25,6 +25,7 @@
 #include "main-channel.h"
 #include "red-channel-client.h"
 #include "red-client.h"
+#include "red-pipe-item-enums.h"
 #include "reds.h"
 
 #define NET_TEST_WARMUP_BYTES 0
@@ -210,6 +211,7 @@ static void main_channel_client_class_init(MainChannelClientClass *klass)
     object_class->get_property = main_channel_client_get_property;
     object_class->set_property = main_channel_client_set_property;
 
+    client_class->red_pipe_item_type = MAIN_CHANNEL_PIPE_ITEM_TYPE;
     client_class->alloc_recv_buf = main_channel_client_alloc_msg_rcv_buf;
     client_class->release_recv_buf = main_channel_client_release_msg_rcv_buf;
     client_class->on_disconnect = main_channel_client_on_disconnect;
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index ca0a6d19f..5be4a40dc 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -35,6 +35,7 @@
 
 #include "red-channel-client.h"
 #include "red-client.h"
+#include "red-pipe-item-enums.h"
 #include "glib-compat.h"
 
 #define CLIENT_ACK_WINDOW 20
@@ -406,6 +407,8 @@ static void red_channel_client_class_init(RedChannelClientClass *klass)
     g_debug("%s", G_STRFUNC);
     g_type_class_add_private(klass, sizeof(RedChannelClientPrivate));
 
+    klass->red_pipe_item_type = RED_CHANNEL_PIPE_ITEM_TYPE;
+
     object_class->get_property = red_channel_client_get_property;
     object_class->set_property = red_channel_client_set_property;
     object_class->finalize = red_channel_client_finalize;
@@ -1898,3 +1901,39 @@ GQuark spice_server_error_quark(void)
 {
     return g_quark_from_static_string("spice-server-error-quark");
 }
+
+const char *red_channel_client_get_pipe_item_name(RedChannelClient *rcc, RedPipeItem *item)
+{
+    RedChannelClientClass *klass;
+    GEnumValue *enum_value = NULL;
+
+    g_return_val_if_fail(RED_IS_CHANNEL_CLIENT(rcc), NULL);
+    klass = RED_CHANNEL_CLIENT_GET_CLASS(rcc);
+    g_return_val_if_fail(G_TYPE_IS_ENUM(klass->red_pipe_item_type), NULL);
+
+    while (RED_IS_CHANNEL_CLIENT_CLASS(klass)) {
+        GEnumClass *enum_class;
+
+        enum_class = g_type_class_ref(klass->red_pipe_item_type);
+        if (item->type < enum_class->minimum) {
+            g_type_class_unref(enum_class);
+            klass = g_type_class_peek_parent(klass);
+            continue;
+        }
+
+        if (item->type > enum_class->maximum) {
+            g_type_class_unref(enum_class);
+            g_warn_if_reached();
+            break;
+        }
+
+        enum_value = g_enum_get_value(enum_class, item->type);
+        g_type_class_unref(enum_class);
+        break;
+    }
+
+    if (enum_value != NULL)
+        return enum_value->value_name;
+
+    g_return_val_if_reached(NULL);
+}
diff --git a/server/red-channel-client.h b/server/red-channel-client.h
index 572831dd3..f0484a400 100644
--- a/server/red-channel-client.h
+++ b/server/red-channel-client.h
@@ -151,6 +151,7 @@ void red_channel_client_init_outgoing_messages_window(RedChannelClient *rcc);
 gboolean red_channel_client_set_migration_seamless(RedChannelClient *rcc);
 void red_channel_client_set_destroying(RedChannelClient *rcc);
 bool red_channel_client_is_destroying(RedChannelClient *rcc);
+const char *red_channel_client_get_pipe_item_name(RedChannelClient *rcc, RedPipeItem *item);
 
 struct RedChannelClient
 {
@@ -162,6 +163,7 @@ struct RedChannelClient
 struct RedChannelClientClass
 {
     GObjectClass parent_class;
+    GType red_pipe_item_type;
 
     /* configure socket connected to the client */
     bool (*config_socket)(RedChannelClient *rcc);
diff --git a/server/smartcard-channel-client.c b/server/smartcard-channel-client.c
index b1652e769..4c6bf2376 100644
--- a/server/smartcard-channel-client.c
+++ b/server/smartcard-channel-client.c
@@ -18,6 +18,7 @@
 #include <config.h>
 #endif
 
+#include "red-pipe-item-enums.h"
 #include "smartcard-channel-client.h"
 
 G_DEFINE_TYPE(SmartCardChannelClient, smart_card_channel_client, RED_TYPE_CHANNEL_CLIENT)
@@ -91,6 +92,7 @@ static void smart_card_channel_client_class_init(SmartCardChannelClientClass *kl
     g_type_class_add_private(klass, sizeof(SmartCardChannelClientPrivate));
 
     RedChannelClientClass *client_class = RED_CHANNEL_CLIENT_CLASS(klass);
+    client_class->red_pipe_item_type = SMARTCARD_CHANNEL_PIPE_ITEM_TYPE;
     client_class->alloc_recv_buf = smartcard_channel_client_alloc_msg_rcv_buf;
     client_class->release_recv_buf = smartcard_channel_client_release_msg_rcv_buf;
     client_class->on_disconnect = smartcard_channel_client_on_disconnect;
diff --git a/server/spicevmc.c b/server/spicevmc.c
index fb760944b..1fe9922b5 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -316,13 +316,37 @@ typedef struct RedPortEventPipeItem {
     uint8_t event;
 } RedPortEventPipeItem;
 
-enum {
+typedef enum {
     RED_PIPE_ITEM_TYPE_SPICEVMC_DATA = RED_PIPE_ITEM_TYPE_CHANNEL_BASE,
     RED_PIPE_ITEM_TYPE_SPICEVMC_MIGRATE_DATA,
     RED_PIPE_ITEM_TYPE_PORT_INIT,
     RED_PIPE_ITEM_TYPE_PORT_EVENT,
+} SpiceVmcPipeItemType;
+
+static const GEnumValue _spicevmc_channel_pipe_item_type_values[] = {
+    { RED_PIPE_ITEM_TYPE_SPICEVMC_DATA, "RED_PIPE_ITEM_TYPE_SPICEVMC_DATA", "data" },
+    { RED_PIPE_ITEM_TYPE_SPICEVMC_MIGRATE_DATA, "RED_PIPE_ITEM_TYPE_SPICEVMC_MIGRATE_DATA", "migrate-data" },
+    { RED_PIPE_ITEM_TYPE_PORT_INIT, "RED_PIPE_ITEM_TYPE_PORT_INIT", "port-init" },
+    { RED_PIPE_ITEM_TYPE_PORT_EVENT, "RED_PIPE_ITEM_TYPE_PORT_EVENT", "port-event" },
+    { 0, NULL, NULL }
 };
 
+static GType
+spicevmc_channel_pipe_item_type_get_type (void)
+{
+    static GType type = 0;
+    static volatile gsize type_volatile = 0;
+
+    if (g_once_init_enter(&type_volatile)) {
+        type = g_enum_register_static ("SpiceVmlChannelPipeItemType", _spicevmc_channel_pipe_item_type_values);
+        g_once_init_leave(&type_volatile, type);
+    }
+
+    return type;
+}
+
+#define SPICEVMC_CHANNEL_PIPE_ITEM_TYPE spicevmc_channel_pipe_item_type_get_type()
+
 static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
                                                      uint16_t type,
                                                      uint32_t size,
@@ -987,6 +1011,7 @@ vmc_channel_client_class_init(VmcChannelClientClass *klass)
 {
     RedChannelClientClass *client_class = RED_CHANNEL_CLIENT_CLASS(klass);
 
+    client_class->red_pipe_item_type = SPICEVMC_CHANNEL_PIPE_ITEM_TYPE;
     client_class->alloc_recv_buf = spicevmc_red_channel_alloc_msg_rcv_buf;
     client_class->release_recv_buf = spicevmc_red_channel_release_msg_rcv_buf;
     client_class->on_disconnect = spicevmc_red_channel_client_on_disconnect;
-- 
2.13.6



More information about the Spice-devel mailing list