[Spice-devel] [RFCv5 37/47] server/red_worker: split cursor pipe item from cursor item

Alon Levy alevy at redhat.com
Sun May 8 06:11:33 PDT 2011


Required to support multiple clients.
Also changes somewhat the way we produce PIPE_ITEM_TYPE_LOCAL_CURSOR. Btw,
I haven't managed to see when we actually produce such an item during my
tests.

Previously we had a single pipe item per CursorItem, this is impossible
with two pipes, which happens when we have two clients.
---
 server/red_worker.c |   88 +++++++++++++++++++++++++++++---------------------
 1 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index 78d2db2..409b010 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -318,13 +318,17 @@ enum {
 };
 
 typedef struct CursorItem {
-    PipeItem pipe_data;
     uint32_t group_id;
     int refs;
     int type;
     RedCursorCmd *red_cursor;
 } CursorItem;
 
+typedef struct CursorPipeItem {
+    PipeItem base;
+    CursorItem *cursor_item;
+} CursorPipeItem;
+
 typedef struct LocalCursor {
     CursorItem base;
     SpicePoint16 position;
@@ -4448,8 +4452,6 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
     PANIC_ON(!(cursor_item = alloc_cursor_item(worker)));
 
     cursor_item->refs = 1;
-    red_channel_pipe_item_init(&worker->cursor_channel->common.base,
-                        &cursor_item->pipe_data, PIPE_ITEM_TYPE_CURSOR);
     cursor_item->type = CURSOR_TYPE_INVALID;
     cursor_item->group_id = group_id;
     cursor_item->red_cursor = cmd;
@@ -4457,17 +4459,24 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
     return cursor_item;
 }
 
-static PipeItem *ref_cursor_pipe_item(RedChannelClient *rcc, void *data, int num)
+static PipeItem *new_cursor_pipe_item(RedChannelClient *rcc, void *data, int num)
 {
-    CursorItem *cursor_item = data;
+    CursorPipeItem *item = spice_malloc0(sizeof(CursorPipeItem));
+    RedWorker *worker = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base)->worker;
 
-    cursor_item->refs += (num != 0); /* we already reference the first use */
-    return &cursor_item->pipe_data;
+    if (worker->cursor && worker->cursor->type == CURSOR_TYPE_LOCAL) {
+        red_channel_pipe_item_init(rcc->channel, &item->base, PIPE_ITEM_TYPE_LOCAL_CURSOR);
+    } else {
+        red_channel_pipe_item_init(rcc->channel, &item->base, PIPE_ITEM_TYPE_CURSOR);
+    }
+    item->cursor_item = data;
+    item->cursor_item->refs++;
+    return &item->base;
 }
 
 static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint32_t group_id)
 {
-    CursorItem *item;
+    CursorItem *cursor_item;
     int cursor_show = FALSE;
 
     if (!cursor_is_connected(worker)) {
@@ -4475,13 +4484,13 @@ static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint
         free(cursor_cmd);
         return;
     }
-    item = get_cursor_item(worker, cursor_cmd, group_id);
+    cursor_item = get_cursor_item(worker, cursor_cmd, group_id);
 
     switch (cursor_cmd->type) {
     case QXL_CURSOR_SET:
         worker->cursor_visible = cursor_cmd->u.set.visible;
-        item->type = CURSOR_TYPE_DEV;
-        red_set_cursor(worker, item);
+        cursor_item->type = CURSOR_TYPE_DEV;
+        red_set_cursor(worker, cursor_item);
         break;
     case QXL_CURSOR_MOVE:
         cursor_show = !worker->cursor_visible;
@@ -4501,11 +4510,10 @@ static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint
 
     if (cursor_is_connected(worker) && (worker->mouse_mode == SPICE_MOUSE_MODE_SERVER ||
                                    cursor_cmd->type != QXL_CURSOR_MOVE || cursor_show)) {
-        red_channel_pipes_new_add(&worker->cursor_channel->common.base, ref_cursor_pipe_item,
-                                  (void*)item);
-    } else {
-        red_release_cursor(worker, item);
+        red_channel_pipes_new_add(&worker->cursor_channel->common.base, new_cursor_pipe_item,
+                                  (void*)cursor_item);
     }
+    red_release_cursor(worker, cursor_item);
 }
 
 static inline uint64_t red_now()
@@ -8299,7 +8307,8 @@ static void red_cursor_marshall_inval(RedChannelClient *rcc,
     red_marshall_inval(rcc, m, cach_item);
 }
 
-static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *base_marshaller)
+static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *base_marshaller,
+                                     PipeItem *pipe_item)
 {
     CursorChannel *cursor_channel;
     CursorChannelClient *ccc = RCC_TO_CCC(rcc);
@@ -8311,7 +8320,7 @@ static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *bas
     cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
     worker = cursor_channel->common.worker;
 
-    red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INIT, &worker->cursor->pipe_data);
+    red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INIT, pipe_item);
     msg.visible = worker->cursor_visible;
     msg.position = worker->cursor_position;
     msg.trail_length = worker->cursor_trail_length;
@@ -8323,17 +8332,19 @@ static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *bas
 }
 
 static void red_marshall_local_cursor(RedChannelClient *rcc,
-          SpiceMarshaller *base_marshaller, LocalCursor *cursor)
+          SpiceMarshaller *base_marshaller, CursorPipeItem *pipe_item)
 {
     CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
     CursorChannelClient *ccc = RCC_TO_CCC(rcc);
+    LocalCursor *cursor = SPICE_CONTAINEROF(pipe_item->cursor_item, LocalCursor, base);
+
     SpiceMsgCursorSet cursor_set;
     AddBufInfo info;
     RedWorker *worker;
 
     ASSERT(cursor_channel);
     worker = cursor_channel->common.worker;
-    red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, &cursor->base.pipe_data);
+    red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, &pipe_item->base);
     cursor_set.position = cursor->position;
     cursor_set.visible = worker->cursor_visible;
 
@@ -8355,10 +8366,12 @@ static void cursor_channel_marshall_migrate(RedChannelClient *rcc,
 }
 
 static void red_marshall_cursor(RedChannelClient *rcc,
-                   SpiceMarshaller *m, CursorItem *cursor)
+                   SpiceMarshaller *m, CursorPipeItem *cursor_pipe_item)
 {
     CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
     CursorChannelClient *ccc = RCC_TO_CCC(rcc);
+    CursorItem *cursor = cursor_pipe_item->cursor_item;
+    PipeItem *pipe_item = &cursor_pipe_item->base;
     RedCursorCmd *cmd;
     RedWorker *worker;
 
@@ -8371,7 +8384,7 @@ static void red_marshall_cursor(RedChannelClient *rcc,
     case QXL_CURSOR_MOVE:
         {
             SpiceMsgCursorMove cursor_move;
-            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_MOVE, &cursor->pipe_data);
+            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_MOVE, pipe_item);
             cursor_move.position = cmd->u.position;
             spice_marshall_msg_cursor_move(m, &cursor_move);
             break;
@@ -8381,7 +8394,7 @@ static void red_marshall_cursor(RedChannelClient *rcc,
             SpiceMsgCursorSet cursor_set;
             AddBufInfo info;
 
-            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, &cursor->pipe_data);
+            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, pipe_item);
             cursor_set.position = cmd->u.set.position;
             cursor_set.visible = worker->cursor_visible;
 
@@ -8391,13 +8404,13 @@ static void red_marshall_cursor(RedChannelClient *rcc,
             break;
         }
     case QXL_CURSOR_HIDE:
-        red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_HIDE, &cursor->pipe_data);
+        red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_HIDE, pipe_item);
         break;
     case QXL_CURSOR_TRAIL:
         {
             SpiceMsgCursorTrail cursor_trail;
 
-            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_TRAIL, &cursor->pipe_data);
+            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_TRAIL, pipe_item);
             cursor_trail.length = cmd->u.trail.length;
             cursor_trail.frequency = cmd->u.trail.frequency;
             spice_marshall_msg_cursor_trail(m, &cursor_trail);
@@ -8406,7 +8419,6 @@ static void red_marshall_cursor(RedChannelClient *rcc,
     default:
         red_error("bad cursor command %d", cmd->type);
     }
-    red_release_cursor(worker, cursor);
 }
 
 static void red_marshall_surface_create(RedChannelClient *rcc,
@@ -8518,10 +8530,10 @@ static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item)
 
     switch (pipe_item->type) {
     case PIPE_ITEM_TYPE_CURSOR:
-        red_marshall_cursor(rcc, m, (CursorItem *)pipe_item);
+        red_marshall_cursor(rcc, m, SPICE_CONTAINEROF(pipe_item, CursorPipeItem, base));
         break;
     case PIPE_ITEM_TYPE_LOCAL_CURSOR:
-        red_marshall_local_cursor(rcc, m, (LocalCursor *)pipe_item);
+        red_marshall_local_cursor(rcc, m, SPICE_CONTAINEROF(pipe_item, CursorPipeItem, base));
         break;
     case PIPE_ITEM_TYPE_INVAL_ONE:
         red_cursor_marshall_inval(rcc, m, (CacheItem *)pipe_item);
@@ -8538,8 +8550,7 @@ static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item)
         break;
     case PIPE_ITEM_TYPE_CURSOR_INIT:
         red_reset_cursor_cache(rcc);
-        red_marshall_cursor_init(rcc, m);
-        free(pipe_item);
+        red_marshall_cursor_init(rcc, m, pipe_item);
         break;
     case PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE:
         red_reset_cursor_cache(rcc);
@@ -9983,11 +9994,17 @@ static void cursor_channel_release_item(RedChannelClient *rcc, PipeItem *item, i
 
     ASSERT(item);
     switch (item->type) {
-        case PIPE_ITEM_TYPE_CURSOR:
-            red_release_cursor(common->worker, SPICE_CONTAINEROF(item, CursorItem, pipe_data));
-            break;
-        default:
-            PANIC("invalid item type");
+    case PIPE_ITEM_TYPE_CURSOR: {
+        CursorPipeItem *cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
+        red_release_cursor(common->worker, cursor_pipe_item->cursor_item);
+        free(cursor_pipe_item);
+        break;
+    }
+    case PIPE_ITEM_TYPE_CURSOR_INIT:
+        free(item);
+        break;
+    default:
+        PANIC("invalid item type");
     }
 }
 
@@ -10055,9 +10072,6 @@ static LocalCursor *_new_local_cursor(RedChannel *channel,
     LocalCursor *local;
 
     local = (LocalCursor *)spice_malloc0(sizeof(LocalCursor) + data_size);
-
-    red_channel_pipe_item_init(channel, &local->base.pipe_data,
-                               PIPE_ITEM_TYPE_LOCAL_CURSOR);
     local->base.refs = 1;
     local->base.type = CURSOR_TYPE_LOCAL;
 
-- 
1.7.5.1



More information about the Spice-devel mailing list