[Spice-devel] [RFCv5 31/47] server/red_worker: add ref counting to RedDrawable

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


When we start having multiple clients each
drawable will be referenced by multiple clients, release happens when all
clients are done with it.
---
 server/red_parse_qxl.h |    1 +
 server/red_worker.c    |   17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h
index 5de0325..fd14581 100644
--- a/server/red_parse_qxl.h
+++ b/server/red_parse_qxl.h
@@ -24,6 +24,7 @@
 #include "red_memslots.h"
 
 typedef struct RedDrawable {
+    int refs; // used by multiple clients
     QXLReleaseInfo *release_info;
     uint32_t surface_id;
     uint8_t effect;
diff --git a/server/red_worker.c b/server/red_worker.c
index db8d9d9..5295af5 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1583,6 +1583,10 @@ static inline void free_red_drawable(RedWorker *worker, RedDrawable *drawable, u
     if (self_bitmap) {
         red_put_image(self_bitmap);
     }
+    if (--drawable->refs) {
+        return;
+    }
+
     release_info_ext.group_id = group_id;
     release_info_ext.info = drawable->release_info;
     worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
@@ -3465,6 +3469,7 @@ static Drawable *get_drawable(RedRender *render, uint8_t effect, RedDrawable *re
     red_channel_pipe_item_init(&worker->display_channel->common.base,
         &drawable->pipe_item, PIPE_ITEM_TYPE_DRAW);
     drawable->red_drawable = red_drawable;
+    red_drawable->refs++;
     drawable->group_id = group_id;
 
     drawable->surface_id = red_drawable->surface_id;
@@ -4528,6 +4533,14 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ri
     return n;
 }
 
+static RedDrawable *red_drawable_new(void)
+{
+    RedDrawable * red = spice_new0(RedDrawable, 1);
+
+    red->refs = 1;
+    return red;
+}
+
 static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *ring_is_empty)
 {
     QXLCommandExt ext_cmd;
@@ -4555,11 +4568,13 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
         worker->repoll_cmd_ring = 0;
         switch (ext_cmd.cmd.type) {
         case QXL_CMD_DRAW: {
-            RedDrawable *drawable = spice_new0(RedDrawable, 1);
+            RedDrawable *drawable = red_drawable_new(); // returns with 1 ref
 
             red_get_drawable(&worker->mem_slots, ext_cmd.group_id,
                              drawable, ext_cmd.cmd.data, ext_cmd.flags);
             red_process_drawable(worker, drawable, ext_cmd.group_id);
+            // release the red_drawable
+            free_red_drawable(worker, drawable, ext_cmd.group_id, NULL);
             break;
         }
         case QXL_CMD_UPDATE: {
-- 
1.7.5.1



More information about the Spice-devel mailing list