[Spice-commits] 2 commits - server/cursor-channel.c server/cursor-channel.h server/red_channel.c server/red_channel.h server/red_worker.c server/red_worker.h

Frediano Ziglio fziglio at kemper.freedesktop.org
Tue Nov 3 01:07:59 PST 2015


 server/cursor-channel.c |  101 ++++++++++++++++++++++++++++++++++++++++-
 server/cursor-channel.h |   66 ++-------------------------
 server/red_channel.c    |   12 ++++
 server/red_channel.h    |    8 +++
 server/red_worker.c     |  116 ++++++++++++++++++++----------------------------
 server/red_worker.h     |    6 ++
 6 files changed, 179 insertions(+), 130 deletions(-)

New commits:
commit e601e920bd5a8385f7388cf31e0b0d543f68193e
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Sep 3 22:24:44 2013 +0200

    server: make more of cursor private
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 48f9ad3..91eb55d 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -19,6 +19,41 @@
 #include "common/generated_server_marshallers.h"
 #include "cursor-channel.h"
 
+#define CLIENT_CURSOR_CACHE_SIZE 256
+
+#define CURSOR_CACHE_HASH_SHIFT 8
+#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT)
+#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1)
+#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK)
+
+enum {
+    PIPE_ITEM_TYPE_CURSOR = PIPE_ITEM_TYPE_COMMON_LAST,
+    PIPE_ITEM_TYPE_CURSOR_INIT,
+    PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
+};
+
+typedef struct CursorItem {
+    QXLInstance *qxl;
+    uint32_t group_id;
+    int refs;
+    RedCursorCmd *red_cursor;
+} CursorItem;
+
+G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
+
+typedef struct LocalCursor {
+    CursorItem base;
+    SpicePoint16 position;
+    uint32_t data_size;
+    SpiceCursor red_cursor;
+} LocalCursor;
+
+typedef struct CursorPipeItem {
+    PipeItem base;
+    CursorItem *cursor_item;
+    int refs;
+} CursorPipeItem;
+
 struct CursorChannel {
     CommonChannel common; // Must be the first thing
 
@@ -34,6 +69,16 @@ struct CursorChannel {
 #endif
 };
 
+struct CursorChannelClient {
+    CommonChannelClient common;
+
+    CacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE];
+    Ring cursor_cache_lru;
+    long cursor_cache_available;
+    uint32_t cursor_cache_items;
+};
+
+
 #define RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient, common.base)
 
 #define CLIENT_CURSOR_CACHE
@@ -50,7 +95,7 @@ static inline CursorItem *alloc_cursor_item(void)
     return cursor_item;
 }
 
-CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
+static CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
 {
     CursorItem *cursor_item;
 
@@ -63,7 +108,7 @@ CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
     return cursor_item;
 }
 
-void cursor_item_unref(QXLInstance *qxl, CursorItem *cursor)
+static void cursor_item_unref(QXLInstance *qxl, CursorItem *cursor)
 {
     if (!--cursor->refs) {
         QXLReleaseInfoExt release_info_ext;
@@ -390,6 +435,17 @@ CursorChannel* cursor_channel_new(RedWorker *worker)
     return cursor_channel;
 }
 
+void cursor_channel_client_migrate(CursorChannelClient* client)
+{
+    RedChannelClient *rcc;
+
+    spice_return_if_fail(client);
+    rcc = RED_CHANNEL_CLIENT(client);
+
+    red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
+    red_channel_client_default_migrate(rcc);
+}
+
 CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream,
                                                int mig_target,
                                                uint32_t *common_caps, int num_common_caps,
@@ -476,6 +532,23 @@ void cursor_channel_reset(CursorChannel *cursor)
     }
 }
 
+void cursor_channel_init(CursorChannel *cursor, CursorChannelClient *client)
+{
+    spice_return_if_fail(cursor);
+
+    if (red_channel_is_connected(&cursor->common.base)
+        || COMMON_CHANNEL(cursor)->during_target_migrate) {
+        spice_debug("during_target_migrate: skip init");
+        return;
+    }
+
+    if (client)
+        red_channel_client_pipe_add_type(RED_CHANNEL_CLIENT(client),
+                                         PIPE_ITEM_TYPE_CURSOR_INIT);
+    else
+        red_channel_pipes_add_type(RED_CHANNEL(cursor), PIPE_ITEM_TYPE_CURSOR_INIT);
+}
+
 void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
 {
     spice_return_if_fail(cursor);
diff --git a/server/cursor-channel.h b/server/cursor-channel.h
index 5d4f8ea..887f847 100644
--- a/server/cursor-channel.h
+++ b/server/cursor-channel.h
@@ -25,66 +25,24 @@
 #include "cache-item.h"
 #include "stat.h"
 
-#define CLIENT_CURSOR_CACHE_SIZE 256
-
-#define CURSOR_CACHE_HASH_SHIFT 8
-#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT)
-#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1)
-#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK)
-
-enum {
-    PIPE_ITEM_TYPE_CURSOR = PIPE_ITEM_TYPE_COMMON_LAST,
-    PIPE_ITEM_TYPE_CURSOR_INIT,
-    PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
-};
-
 typedef struct CursorChannel CursorChannel;
+typedef struct CursorChannelClient CursorChannelClient;
 
-typedef struct CursorItem {
-    uint32_t group_id;
-    int refs;
-    RedCursorCmd *red_cursor;
-} CursorItem;
-
-typedef struct CursorPipeItem {
-    PipeItem base;
-    CursorItem *cursor_item;
-    int refs;
-} CursorPipeItem;
-
-typedef struct LocalCursor {
-    CursorItem base;
-    SpicePoint16 position;
-    uint32_t data_size;
-    SpiceCursor red_cursor;
-} LocalCursor;
-
-typedef struct CursorChannelClient {
-    CommonChannelClient common;
-
-    CacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE];
-    Ring cursor_cache_lru;
-    long cursor_cache_available;
-    uint32_t cursor_cache_items;
-} CursorChannelClient;
-
-G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
+#define CURSOR_CHANNEL_CLIENT(Client) ((CursorChannelClient*)(Client))
 
 CursorChannel*       cursor_channel_new         (RedWorker *worker);
 void                 cursor_channel_disconnect  (CursorChannel *cursor_channel);
 void                 cursor_channel_reset       (CursorChannel *cursor);
+void                 cursor_channel_init        (CursorChannel *cursor, CursorChannelClient* client);
 void                 cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd,
                                                  uint32_t group_id);
 void                 cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode);
 
-CursorItem*          cursor_item_new            (RedCursorCmd *cmd, uint32_t group_id);
-void                 cursor_item_unref          (QXLInstance *qxl, CursorItem *cursor);
-
-
 CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor,
                                                RedClient *client, RedsStream *stream,
                                                int mig_target,
                                                uint32_t *common_caps, int num_common_caps,
                                                uint32_t *caps, int num_caps);
+void                 cursor_channel_client_migrate(CursorChannelClient* client);
 
 #endif /* CURSOR_CHANNEL_H_ */
diff --git a/server/red_channel.h b/server/red_channel.h
index 201a4d2..eda4436 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -302,6 +302,8 @@ struct RedChannelClient {
     RedChannelClientConnectivityMonitor connectivity_monitor;
 };
 
+#define RED_CHANNEL_CLIENT(Client) ((RedChannelClient *)(Client))
+
 struct RedChannel {
     uint32_t type;
     uint32_t id;
diff --git a/server/red_worker.c b/server/red_worker.c
index ecfdea1..a15d5b6 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9065,7 +9065,7 @@ static int common_channel_config_socket(RedChannelClient *rcc)
     RedClient *client = red_channel_client_get_client(rcc);
     MainChannelClient *mcc = red_client_get_main(client);
     RedsStream *stream = red_channel_client_get_stream(rcc);
-    CommonChannelClient *ccc = SPICE_CONTAINEROF(rcc, CommonChannelClient, base);
+    CommonChannelClient *ccc = COMMON_CHANNEL_CLIENT(rcc);
     int flags;
     int delay_val;
 
@@ -9550,14 +9550,14 @@ static void red_connect_cursor(RedWorker *worker, RedClient *client, RedsStream
         return;
     }
 
-    RedChannelClient *rcc = &ccc->common.base;
+    RedChannelClient *rcc = RED_CHANNEL_CLIENT(ccc);
     red_channel_client_ack_zero_messages_window(rcc);
     red_channel_client_push_set_ack(rcc);
+
     // TODO: why do we check for context.canvas? defer this to after display cc is connected
     // and test it's canvas? this is just a test to see if there is an active renderer?
-    if (worker->surfaces[0].context.canvas && !COMMON_CHANNEL(channel)->during_target_migrate) {
-        red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_CURSOR_INIT);
-    }
+    if (worker->surfaces[0].context.canvas)
+        cursor_channel_init(channel, ccc);
 }
 
 static void surface_dirty_region_to_rects(RedSurface *surface,
@@ -9899,11 +9899,7 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
         red_channel_push(&worker->display_channel->common.base);
     }
 
-    if (cursor_is_connected(worker)
-        && !COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate) {
-        red_channel_pipes_add_type(RED_CHANNEL(worker->cursor_channel),
-                                   PIPE_ITEM_TYPE_CURSOR_INIT);
-    }
+    cursor_channel_init(worker->cursor_channel, NULL);
 }
 
 void handle_dev_create_primary_surface(void *opaque, void *payload)
@@ -10289,12 +10285,7 @@ void handle_dev_cursor_migrate(void *opaque, void *payload)
     RedChannelClient *rcc = msg->rcc;
 
     spice_info("migrate cursor client");
-    spice_assert(rcc);
-    if (!red_channel_client_is_connected(rcc))
-        return;
-
-    red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
-    red_channel_client_default_migrate(rcc);
+    cursor_channel_client_migrate(CURSOR_CHANNEL_CLIENT(rcc));
 }
 
 void handle_dev_set_compression(void *opaque, void *payload)
diff --git a/server/red_worker.h b/server/red_worker.h
index e78d5c2..d7a94fd 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -33,6 +33,7 @@ typedef struct CommonChannelClient {
     int is_low_bandwidth;
 } CommonChannelClient;
 
+#define COMMON_CHANNEL_CLIENT(Client) ((CommonChannelClient*)(Client))
 #define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
 
 #define CHANNEL_RECEIVE_BUF_SIZE 1024
commit c9e3b058e452e3e00ae009163a5de66e99987492
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Sep 3 19:35:09 2013 +0200

    server: make cursor channel private
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index eef0121..48f9ad3 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -19,6 +19,21 @@
 #include "common/generated_server_marshallers.h"
 #include "cursor-channel.h"
 
+struct CursorChannel {
+    CommonChannel common; // Must be the first thing
+
+    CursorItem *item;
+    int cursor_visible;
+    SpicePoint16 cursor_position;
+    uint16_t cursor_trail_length;
+    uint16_t cursor_trail_frequency;
+    uint32_t mouse_mode;
+
+#ifdef RED_STATISTICS
+    StatNodeRef stat;
+#endif
+};
+
 #define RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient, common.base)
 
 #define CLIENT_CURSOR_CACHE
@@ -364,7 +379,7 @@ CursorChannel* cursor_channel_new(RedWorker *worker)
     };
 
     spice_info("create cursor channel");
-    channel = red_worker_new_channel(worker, sizeof(CursorChannel),
+    channel = red_worker_new_channel(worker, sizeof(CursorChannel), "cursor_channel",
                                      SPICE_CHANNEL_CURSOR, 0,
                                      &cbs, red_channel_client_handle_message);
 
@@ -460,3 +475,10 @@ void cursor_channel_reset(CursorChannel *cursor)
         }
     }
 }
+
+void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
+{
+    spice_return_if_fail(cursor);
+
+    cursor->mouse_mode = mode;
+}
diff --git a/server/cursor-channel.h b/server/cursor-channel.h
index 67e6e3f..5d4f8ea 100644
--- a/server/cursor-channel.h
+++ b/server/cursor-channel.h
@@ -38,6 +38,8 @@ enum {
     PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
 };
 
+typedef struct CursorChannel CursorChannel;
+
 typedef struct CursorItem {
     uint32_t group_id;
     int refs;
@@ -66,21 +68,6 @@ typedef struct CursorChannelClient {
     uint32_t cursor_cache_items;
 } CursorChannelClient;
 
-typedef struct CursorChannel {
-    CommonChannel common; // Must be the first thing
-
-    CursorItem *item;
-    int cursor_visible;
-    SpicePoint16 cursor_position;
-    uint16_t cursor_trail_length;
-    uint16_t cursor_trail_frequency;
-    uint32_t mouse_mode;
-
-#ifdef RED_STATISTICS
-    StatNodeRef stat;
-#endif
-} CursorChannel;
-
 G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
 
 CursorChannel*       cursor_channel_new         (RedWorker *worker);
@@ -88,6 +75,7 @@ void                 cursor_channel_disconnect  (CursorChannel *cursor_channel);
 void                 cursor_channel_reset       (CursorChannel *cursor);
 void                 cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd,
                                                  uint32_t group_id);
+void                 cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode);
 
 CursorItem*          cursor_item_new            (RedCursorCmd *cmd, uint32_t group_id);
 void                 cursor_item_unref          (QXLInstance *qxl, CursorItem *cursor);
diff --git a/server/red_channel.c b/server/red_channel.c
index 34aa9dc..7330ae2 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1151,9 +1151,21 @@ RedChannel *red_channel_create_parser(int size,
     }
     channel->incoming_cb.handle_parsed = (handle_parsed_proc)handle_parsed;
     channel->incoming_cb.parser = parser;
+
     return channel;
 }
 
+void red_channel_set_stat_node(RedChannel *channel, StatNodeRef stat)
+{
+    spice_return_if_fail(channel != NULL);
+    spice_return_if_fail(channel->stat == 0);
+
+#ifdef RED_STATISTICS
+    channel->stat = stat;
+    channel->out_bytes_counter = stat_add_counter(stat, "out_bytes", TRUE);
+#endif
+}
+
 void red_channel_register_client_cbs(RedChannel *channel, ClientCbs *client_cbs)
 {
     spice_assert(client_cbs->connect || channel->type == SPICE_CHANNEL_MAIN);
diff --git a/server/red_channel.h b/server/red_channel.h
index 1f1538e..201a4d2 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -32,6 +32,7 @@
 #include "red_common.h"
 #include "demarshallers.h"
 #include "reds_stream.h"
+#include "stat.h"
 
 #define MAX_SEND_BUFS 1000
 #define CLIENT_ACK_WINDOW 20
@@ -127,6 +128,7 @@ typedef struct OutgoingHandler {
 
 /* Red Channel interface */
 
+typedef struct RedsStream RedsStream;
 typedef struct RedChannel RedChannel;
 typedef struct RedChannelClient RedChannelClient;
 typedef struct RedClient RedClient;
@@ -335,10 +337,13 @@ struct RedChannel {
     // TODO: when different channel_clients are in different threads from Channel -> need to protect!
     pthread_t thread_id;
 #ifdef RED_STATISTICS
+    StatNodeRef stat;
     uint64_t *out_bytes_counter;
 #endif
 };
 
+#define RED_CHANNEL(Channel) ((RedChannel *)(Channel))
+
 /*
  * When an error occurs over a channel, we treat it as a warning
  * for spice-server and shutdown the channel.
@@ -370,6 +375,7 @@ RedChannel *red_channel_create_parser(int size,
                                channel_handle_parsed_proc handle_parsed,
                                ChannelCbs *channel_cbs,
                                uint32_t migration_flags);
+void red_channel_set_stat_node(RedChannel *channel, StatNodeRef stat);
 
 void red_channel_register_client_cbs(RedChannel *channel, ClientCbs *client_cbs);
 // caps are freed when the channel is destroyed
diff --git a/server/red_worker.c b/server/red_worker.c
index e3999ba..ecfdea1 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -391,7 +391,6 @@ struct DisplayChannel {
     RedCompressBuf *free_compress_bufs;
 
 #ifdef RED_STATISTICS
-    StatNodeRef stat;
     uint64_t *cache_hits_counter;
     uint64_t *add_to_cache_counter;
     uint64_t *non_cache_counter;
@@ -875,8 +874,8 @@ static int display_is_connected(RedWorker *worker)
 
 static int cursor_is_connected(RedWorker *worker)
 {
-    return (worker->cursor_channel && red_channel_is_connected(
-        &worker->cursor_channel->common.base));
+    return worker->cursor_channel &&
+        red_channel_is_connected(RED_CHANNEL(worker->cursor_channel));
 }
 
 static void put_drawable_pipe_item(DrawablePipeItem *dpi)
@@ -1135,7 +1134,7 @@ static inline void red_destroy_surface_item(RedWorker *worker,
         return;
     }
     dcc->surface_client_created[surface_id] = FALSE;
-    channel = &worker->display_channel->common.base;
+    channel = RED_CHANNEL(worker->display_channel);
     destroy = get_surface_destroy_item(channel, surface_id);
     red_channel_client_pipe_add(&dcc->common.base, &destroy->pipe_item);
 }
@@ -2795,7 +2794,7 @@ static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, TreeI
 
             /* sending the drawable to clients that already received
              * (or will receive) other_drawable */
-            worker_ring_item = ring_get_head(&worker->display_channel->common.base.clients);
+            worker_ring_item = ring_get_head(&RED_CHANNEL(worker->display_channel)->clients);
             dpi_ring_item = ring_get_head(&other_drawable->pipes);
             /* dpi contains a sublist of dcc's, ordered the same */
             while (worker_ring_item) {
@@ -2804,7 +2803,7 @@ static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, TreeI
                 dpi = SPICE_CONTAINEROF(dpi_ring_item, DrawablePipeItem, base);
                 while (worker_ring_item && (!dpi || dcc != dpi->dcc)) {
                     red_pipe_add_drawable(dcc, drawable);
-                    worker_ring_item = ring_next(&worker->display_channel->common.base.clients,
+                    worker_ring_item = ring_next(&RED_CHANNEL(worker->display_channel)->clients,
                                                  worker_ring_item);
                     dcc = SPICE_CONTAINEROF(worker_ring_item, DisplayChannelClient,
                                             common.base.channel_link);
@@ -2814,7 +2813,7 @@ static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, TreeI
                     dpi_ring_item = ring_next(&other_drawable->pipes, dpi_ring_item);
                 }
                 if (worker_ring_item) {
-                    worker_ring_item = ring_next(&worker->display_channel->common.base.clients,
+                    worker_ring_item = ring_next(&RED_CHANNEL(worker->display_channel)->clients,
                                                  worker_ring_item);
                 }
             }
@@ -3943,7 +3942,7 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ri
 
     *ring_is_empty = FALSE;
     while (!cursor_is_connected(worker) ||
-           red_channel_min_pipe_size(&worker->cursor_channel->common.base) <= max_pipe_size) {
+           red_channel_min_pipe_size(RED_CHANNEL(worker->cursor_channel)) <= max_pipe_size) {
         if (!worker->qxl->st->qif->get_cursor_command(worker->qxl, &ext_cmd)) {
             *ring_is_empty = TRUE;
             if (worker->cursor_poll_tries < CMD_RING_POLL_RETRIES) {
@@ -4005,7 +4004,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
     *ring_is_empty = FALSE;
     while (!display_is_connected(worker) ||
            // TODO: change to average pipe size?
-           red_channel_min_pipe_size(&worker->display_channel->common.base) <= max_pipe_size) {
+           red_channel_min_pipe_size(RED_CHANNEL(worker->display_channel)) <= max_pipe_size) {
         if (!worker->qxl->st->qif->get_command(worker->qxl, &ext_cmd)) {
             *ring_is_empty = TRUE;;
             if (worker->display_poll_tries < CMD_RING_POLL_RETRIES) {
@@ -4150,7 +4149,7 @@ static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
 {
     DisplayChannel *display_channel = DCC_TO_DC(dcc);
     RedWorker *worker = display_channel->common.worker;
-    RedChannel *channel = &display_channel->common.base;
+    RedChannel *channel = RED_CHANNEL(display_channel);
     RedSurface *surface = &worker->surfaces[surface_id];
     SpiceCanvas *canvas = surface->context.canvas;
     ImageItem *item;
@@ -4329,7 +4328,7 @@ static void red_display_reset_compress_buf(DisplayChannelClient *dcc)
 
 static void red_display_destroy_compress_bufs(DisplayChannel *display_channel)
 {
-    spice_assert(!red_channel_is_connected(&display_channel->common.base));
+    spice_assert(!red_channel_is_connected(RED_CHANNEL(display_channel)));
     while (display_channel->free_compress_bufs) {
         RedCompressBuf *buf = display_channel->free_compress_bufs;
         display_channel->free_compress_bufs = buf->next;
@@ -4518,7 +4517,7 @@ static void red_display_clear_glz_drawables(DisplayChannel *display_channel)
     if (!display_channel) {
         return;
     }
-    DCC_FOREACH_SAFE(link, next, dcc, &display_channel->common.base) {
+    DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel)) {
         red_display_client_clear_glz_drawables(dcc);
     }
 }
@@ -8172,10 +8171,10 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
 static inline void red_push(RedWorker *worker)
 {
     if (worker->cursor_channel) {
-        red_channel_push(&worker->cursor_channel->common.base);
+        red_channel_push(RED_CHANNEL(worker->cursor_channel));
     }
     if (worker->display_channel) {
-        red_channel_push(&worker->display_channel->common.base);
+        red_channel_push(RED_CHANNEL(worker->display_channel));
     }
 }
 
@@ -8492,7 +8491,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
 
 static inline void flush_display_commands(RedWorker *worker)
 {
-    RedChannel *display_red_channel = &worker->display_channel->common.base;
+    RedChannel *display_red_channel = RED_CHANNEL(worker->display_channel);
 
     for (;;) {
         uint64_t end_time;
@@ -8504,7 +8503,7 @@ static inline void flush_display_commands(RedWorker *worker)
         }
 
         while (red_process_commands(worker, MAX_PIPE_SIZE, &ring_is_empty)) {
-            red_channel_push(&worker->display_channel->common.base);
+            red_channel_push(RED_CHANNEL(worker->display_channel));
         }
 
         if (ring_is_empty) {
@@ -8513,7 +8512,7 @@ static inline void flush_display_commands(RedWorker *worker)
         end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
         int sleep_count = 0;
         for (;;) {
-            red_channel_push(&worker->display_channel->common.base);
+            red_channel_push(RED_CHANNEL(worker->display_channel));
             if (!display_is_connected(worker) ||
                 red_channel_max_pipe_size(display_red_channel) <= MAX_PIPE_SIZE) {
                 break;
@@ -8536,7 +8535,7 @@ static inline void flush_display_commands(RedWorker *worker)
 
 static inline void flush_cursor_commands(RedWorker *worker)
 {
-    RedChannel *cursor_red_channel = &worker->cursor_channel->common.base;
+    RedChannel *cursor_red_channel = RED_CHANNEL(worker->cursor_channel);
 
     for (;;) {
         uint64_t end_time;
@@ -8548,7 +8547,7 @@ static inline void flush_cursor_commands(RedWorker *worker)
         }
 
         while (red_process_cursor(worker, MAX_PIPE_SIZE, &ring_is_empty)) {
-            red_channel_push(&worker->cursor_channel->common.base);
+            red_channel_push(RED_CHANNEL(worker->cursor_channel));
         }
 
         if (ring_is_empty) {
@@ -8557,7 +8556,7 @@ static inline void flush_cursor_commands(RedWorker *worker)
         end_time = red_get_monotonic_time() + DISPLAY_CLIENT_TIMEOUT;
         int sleep_count = 0;
         for (;;) {
-            red_channel_push(&worker->cursor_channel->common.base);
+            red_channel_push(RED_CHANNEL(worker->cursor_channel));
             if (!cursor_is_connected(worker)
                 || red_channel_min_pipe_size(cursor_red_channel) <= MAX_PIPE_SIZE) {
                 break;
@@ -8826,7 +8825,7 @@ static int display_channel_handle_migrate_glz_dictionary(DisplayChannelClient *d
 static int display_channel_handle_migrate_mark(RedChannelClient *rcc)
 {
     DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
-    RedChannel *channel = &display_channel->common.base;
+    RedChannel *channel = RED_CHANNEL(display_channel);
 
     red_channel_pipes_add_type(channel, PIPE_ITEM_TYPE_MIGRATE_DATA);
     return TRUE;
@@ -9210,6 +9209,7 @@ CommonChannelClient *common_channel_new_client(CommonChannel *common,
 
 
 RedChannel *red_worker_new_channel(RedWorker *worker, int size,
+                                   const char *name,
                                    uint32_t channel_type, int migration_flags,
                                    ChannelCbs *channel_cbs,
                                    channel_handle_parsed_proc handle_parsed)
@@ -9234,16 +9234,12 @@ RedChannel *red_worker_new_channel(RedWorker *worker, int size,
                                         handle_parsed,
                                         channel_cbs,
                                         migration_flags);
+    spice_return_val_if_fail(channel, NULL);
+    red_channel_set_stat_node(channel, stat_add_node(worker->stat, name, TRUE));
+
     common = (CommonChannel *)channel;
-    if (!channel) {
-        goto error;
-    }
     common->worker = worker;
     return channel;
-
-error:
-    free(channel);
-    return NULL;
 }
 
 static void display_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
@@ -9398,7 +9394,7 @@ static void display_channel_create(RedWorker *worker, int migrate)
 
     spice_info("create display channel");
     if (!(worker->display_channel = (DisplayChannel *)red_worker_new_channel(
-            worker, sizeof(*display_channel),
+            worker, sizeof(*display_channel), "display_channel",
             SPICE_CHANNEL_DISPLAY,
             SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER,
             &cbs, display_channel_handle_message))) {
@@ -9407,14 +9403,12 @@ static void display_channel_create(RedWorker *worker, int migrate)
     }
     display_channel = worker->display_channel;
 #ifdef RED_STATISTICS
-    display_channel->stat = stat_add_node(worker->stat, "display_channel", TRUE);
-    display_channel->common.base.out_bytes_counter = stat_add_counter(display_channel->stat,
-                                                               "out_bytes", TRUE);
-    display_channel->cache_hits_counter = stat_add_counter(display_channel->stat,
+    RedChannel *channel = RED_CHANNEL(display_channel);
+    display_channel->cache_hits_counter = stat_add_counter(channel->stat,
                                                            "cache_hits", TRUE);
-    display_channel->add_to_cache_counter = stat_add_counter(display_channel->stat,
+    display_channel->add_to_cache_counter = stat_add_counter(channel->stat,
                                                              "add_to_cache", TRUE);
-    display_channel->non_cache_counter = stat_add_counter(display_channel->stat,
+    display_channel->non_cache_counter = stat_add_counter(channel->stat,
                                                           "non_cache", TRUE);
 #endif
     stat_compress_init(&display_channel->lz_stat, lz_stat_name);
@@ -9457,14 +9451,14 @@ static void guest_set_client_capabilities(RedWorker *worker)
         return;
     }
     if ((worker->display_channel == NULL) ||
-        (worker->display_channel->common.base.clients_num == 0)) {
+        (RED_CHANNEL(worker->display_channel)->clients_num == 0)) {
         worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE, caps);
     } else {
         // Take least common denominator
         for (i = 0 ; i < sizeof(caps_available) / sizeof(caps_available[0]); ++i) {
             SET_CAP(caps, caps_available[i]);
         }
-        DCC_FOREACH_SAFE(link, next, dcc, &worker->display_channel->common.base) {
+        DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(worker->display_channel)) {
             rcc = (RedChannelClient *)dcc;
             for (i = 0 ; i < sizeof(caps_available) / sizeof(caps_available[0]); ++i) {
                 if (!red_channel_client_test_remote_cap(rcc, caps_available[i]))
@@ -9555,17 +9549,13 @@ static void red_connect_cursor(RedWorker *worker, RedClient *client, RedsStream
     if (!ccc) {
         return;
     }
-#ifdef RED_STATISTICS
-    channel->stat = stat_add_node(worker->stat, "cursor_channel", TRUE);
-    channel->common.base.out_bytes_counter = stat_add_counter(channel->stat, "out_bytes", TRUE);
-#endif
 
     RedChannelClient *rcc = &ccc->common.base;
     red_channel_client_ack_zero_messages_window(rcc);
     red_channel_client_push_set_ack(rcc);
     // TODO: why do we check for context.canvas? defer this to after display cc is connected
     // and test it's canvas? this is just a test to see if there is an active renderer?
-    if (worker->surfaces[0].context.canvas && !channel->common.during_target_migrate) {
+    if (worker->surfaces[0].context.canvas && !COMMON_CHANNEL(channel)->during_target_migrate) {
         red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_CURSOR_INIT);
     }
 }
@@ -9743,9 +9733,9 @@ static inline void dev_destroy_surfaces(RedWorker *worker)
     spice_assert(ring_is_empty(&worker->streams));
 
     if (display_is_connected(worker)) {
-        red_channel_pipes_add_type(&worker->display_channel->common.base,
+        red_channel_pipes_add_type(RED_CHANNEL(worker->display_channel),
                                    PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
-        red_pipes_add_verb(&worker->display_channel->common.base,
+        red_pipes_add_verb(RED_CHANNEL(worker->display_channel),
                            SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
     }
 
@@ -9910,8 +9900,8 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
     }
 
     if (cursor_is_connected(worker)
-        && !worker->cursor_channel->common.during_target_migrate) {
-        red_channel_pipes_add_type(&worker->cursor_channel->common.base,
+        && !COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate) {
+        red_channel_pipes_add_type(RED_CHANNEL(worker->cursor_channel),
                                    PIPE_ITEM_TYPE_CURSOR_INIT);
     }
 }
@@ -10008,14 +9998,14 @@ void handle_dev_stop(void *opaque, void *payload)
      * purge the pipe, send destroy_all_surfaces
      * to the client (there is no such message right now), and start
      * from scratch on the destination side */
-    if (!red_channel_wait_all_sent(&worker->display_channel->common.base,
+    if (!red_channel_wait_all_sent(RED_CHANNEL(worker->display_channel),
                                    DISPLAY_CLIENT_TIMEOUT)) {
-        red_channel_apply_clients(&worker->display_channel->common.base,
+        red_channel_apply_clients(RED_CHANNEL(worker->display_channel),
                                  red_channel_client_disconnect_if_pending_send);
     }
-    if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
+    if (!red_channel_wait_all_sent(RED_CHANNEL(worker->cursor_channel),
                                    DISPLAY_CLIENT_TIMEOUT)) {
-        red_channel_apply_clients(&worker->cursor_channel->common.base,
+        red_channel_apply_clients(RED_CHANNEL(worker->cursor_channel),
                                  red_channel_client_disconnect_if_pending_send);
     }
 }
@@ -10057,7 +10047,7 @@ void handle_dev_start(void *opaque, void *payload)
 
     spice_assert(!worker->running);
     if (worker->cursor_channel) {
-        worker->cursor_channel->common.during_target_migrate = FALSE;
+        COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate = FALSE;
     }
     if (worker->display_channel) {
         worker->display_channel->common.during_target_migrate = FALSE;
@@ -10262,7 +10252,8 @@ void handle_dev_cursor_channel_create(void *opaque, void *payload)
     if (!worker->cursor_channel) {
         worker->cursor_channel = cursor_channel_new(worker);
     }
-    red_channel = &worker->cursor_channel->common.base;
+
+    red_channel = RED_CHANNEL(worker->cursor_channel);
     send_data(worker->channel, &red_channel, sizeof(RedChannel *));
 }
 
@@ -10380,8 +10371,8 @@ void handle_dev_set_mouse_mode(void *opaque, void *payload)
     RedWorkerMessageSetMouseMode *msg = payload;
     RedWorker *worker = opaque;
 
-    worker->cursor_channel->mouse_mode = msg->mode;
-    spice_info("mouse mode %u", worker->cursor_channel->mouse_mode);
+    spice_info("mouse mode %u", msg->mode);
+    cursor_channel_set_mouse_mode(worker->cursor_channel, msg->mode);
 }
 
 void handle_dev_add_memslot_async(void *opaque, void *payload)
diff --git a/server/red_worker.h b/server/red_worker.h
index aa97707..e78d5c2 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -27,6 +27,7 @@ typedef struct RedWorker RedWorker;
 
 typedef struct CommonChannelClient {
     RedChannelClient base;
+
     uint32_t id;
     struct RedWorker *worker;
     int is_low_bandwidth;
@@ -37,6 +38,7 @@ typedef struct CommonChannelClient {
 #define CHANNEL_RECEIVE_BUF_SIZE 1024
 typedef struct CommonChannel {
     RedChannel base; // Must be the first thing
+
     struct RedWorker *worker;
     uint8_t recv_buf[CHANNEL_RECEIVE_BUF_SIZE];
     uint32_t id_alloc; // bitfield. TODO - use this instead of shift scheme.
@@ -47,6 +49,8 @@ typedef struct CommonChannel {
                                   of the primary surface) */
 } CommonChannel;
 
+#define COMMON_CHANNEL(Channel) ((CommonChannel*)(Channel))
+
 enum {
     PIPE_ITEM_TYPE_VERB = PIPE_ITEM_TYPE_CHANNEL_BASE,
     PIPE_ITEM_TYPE_INVAL_ONE,
@@ -104,6 +108,7 @@ bool       red_worker_run(RedWorker *worker);
 QXLInstance* red_worker_get_qxl(RedWorker *worker);
 
 RedChannel *red_worker_new_channel(RedWorker *worker, int size,
+                                   const char *name,
                                    uint32_t channel_type, int migration_flags,
                                    ChannelCbs *channel_cbs,
                                    channel_handle_parsed_proc handle_parsed);


More information about the Spice-commits mailing list