[Spice-devel] [spice-server v4 08/11] qxl: Add red_update_cmd_{new, ref, unref} helpers

Christophe Fergeau cfergeau at redhat.com
Thu Nov 29 12:50:10 UTC 2018


Currently, RedUpdateCmd are allocated on the stack, and then
initialized/uninitialized with red_{get,put}_update_cmd
This makes the API inconsistent with what is being done for RedDrawable,
RedCursor and RedMessage. QXLUpdateCmd are not occurring very often,
we can dynamically allocate them instead, and get a consistent API.
---
 server/red-parse-qxl.c | 38 ++++++++++++++++++++++++++++++++++----
 server/red-parse-qxl.h |  7 ++++---
 server/red-worker.c    | 14 +++++++-------
 3 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
index 1608caff2..00ec8b9c9 100644
--- a/server/red-parse-qxl.c
+++ b/server/red-parse-qxl.c
@@ -1237,9 +1237,8 @@ static void red_put_drawable(RedDrawable *red)
     }
 }
 
-bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
-                        int group_id, RedUpdateCmd *red,
-                        QXLPHYSICAL addr)
+static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
+                               RedUpdateCmd *red, QXLPHYSICAL addr)
 {
     QXLUpdateCmd *qxl;
 
@@ -1257,13 +1256,44 @@ bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
     return true;
 }
 
-void red_put_update_cmd(RedUpdateCmd *red)
+static void red_put_update_cmd(RedUpdateCmd *red)
 {
     if (red->qxl != NULL) {
         red_qxl_release_resource(red->qxl, red->release_info_ext);
     }
 }
 
+RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr)
+{
+    RedUpdateCmd *red;
+
+    red = g_new0(RedUpdateCmd, 1);
+
+    red->refs = 1;
+
+    if (!red_get_update_cmd(qxl, slots, group_id, red, addr)) {
+        red_update_cmd_unref(red);
+        return NULL;
+    }
+
+    return red;
+}
+
+RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red)
+{
+    red->refs++;
+    return red;
+}
+
+void red_update_cmd_unref(RedUpdateCmd *red)
+{
+    if (--red->refs) {
+        return;
+    }
+    red_put_update_cmd(red);
+    g_free(red);
+}
+
 static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
                             RedMessage *red, QXLPHYSICAL addr)
 {
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index f9013161d..d969b3004 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -62,6 +62,7 @@ typedef struct RedDrawable {
 typedef struct RedUpdateCmd {
     QXLInstance *qxl;
     QXLReleaseInfoExt release_info_ext;
+    int refs;
     SpiceRect area;
     uint32_t update_id;
     uint32_t surface_id;
@@ -120,9 +121,9 @@ RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
 RedDrawable *red_drawable_ref(RedDrawable *drawable);
 void red_drawable_unref(RedDrawable *red_drawable);
 
-bool red_get_update_cmd(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id,
-                        RedUpdateCmd *red, QXLPHYSICAL addr);
-void red_put_update_cmd(RedUpdateCmd *red);
+RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
+RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red);
+void red_update_cmd_unref(RedUpdateCmd *red);
 
 RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
 RedMessage *red_message_ref(RedMessage *red);
diff --git a/server/red-worker.c b/server/red-worker.c
index 7c9076c46..7734fc04c 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -213,19 +213,19 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
             break;
         }
         case QXL_CMD_UPDATE: {
-            RedUpdateCmd update;
+            RedUpdateCmd *update;
 
-            if (!red_get_update_cmd(worker->qxl, &worker->mem_slots, ext_cmd.group_id,
-                                    &update, ext_cmd.cmd.data)) {
+            update = red_update_cmd_new(worker->qxl, &worker->mem_slots,  ext_cmd.group_id, ext_cmd.cmd.data);
+            if (update == NULL) {
                 break;
             }
-            if (!display_channel_validate_surface(worker->display_channel, update.surface_id)) {
+            if (!display_channel_validate_surface(worker->display_channel, update->surface_id)) {
                 spice_warning("Invalid surface in QXL_CMD_UPDATE");
             } else {
-                display_channel_draw(worker->display_channel, &update.area, update.surface_id);
-                red_qxl_notify_update(worker->qxl, update.update_id);
+                display_channel_draw(worker->display_channel, &update->area, update->surface_id);
+                red_qxl_notify_update(worker->qxl, update->update_id);
             }
-            red_put_update_cmd(&update);
+            red_update_cmd_unref(update);
             break;
         }
         case QXL_CMD_MESSAGE: {
-- 
2.19.1



More information about the Spice-devel mailing list