Blame SOURCES/0075-char-device-fix-usage-of-free-unref-on-WriteBuffer.patch

e2c81d
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
e2c81d
From: Victor Toso <victortoso@redhat.com>
e2c81d
Date: Wed, 19 Aug 2015 10:53:22 +0200
e2c81d
Subject: [PATCH] char-device: fix usage of free/unref on WriteBuffer
e2c81d
e2c81d
There are places were the could should definetly free the
e2c81d
SpiceCharDeviceWriteBuffer and places that it should only unref it. The
e2c81d
current use of spice_char_device_write_buffer_free was missleading.
e2c81d
e2c81d
This patch creates the spice_char_device_write_buffer_unref and properly
e2c81d
call these two functions.
e2c81d
e2c81d
Related: https://bugs.freedesktop.org/show_bug.cgi?id=91350
e2c81d
---
e2c81d
 server/char_device.c | 34 ++++++++++++++++++++++------------
e2c81d
 1 file changed, 22 insertions(+), 12 deletions(-)
e2c81d
e2c81d
diff --git a/server/char_device.c b/server/char_device.c
e2c81d
index c6dc45b..dd367ab 100644
e2c81d
--- a/server/char_device.c
e2c81d
+++ b/server/char_device.c
e2c81d
@@ -80,6 +80,7 @@ enum {
e2c81d
  * destroyed during a callback */
e2c81d
 static void spice_char_device_state_ref(SpiceCharDeviceState *char_dev);
e2c81d
 static void spice_char_device_state_unref(SpiceCharDeviceState *char_dev);
e2c81d
+static void spice_char_device_write_buffer_unref(SpiceCharDeviceWriteBuffer *write_buf);
e2c81d
 
e2c81d
 static void spice_char_dev_write_retry(void *opaque);
e2c81d
 
e2c81d
@@ -90,10 +91,11 @@ typedef struct SpiceCharDeviceMsgToClientItem {
e2c81d
 
e2c81d
 static void spice_char_device_write_buffer_free(SpiceCharDeviceWriteBuffer *buf)
e2c81d
 {
e2c81d
-    if (--buf->refs == 0) {
e2c81d
-        free(buf->buf);
e2c81d
-        free(buf);
e2c81d
-    }
e2c81d
+    if (buf == NULL)
e2c81d
+        return;
e2c81d
+
e2c81d
+    free(buf->buf);
e2c81d
+    free(buf);
e2c81d
 }
e2c81d
 
e2c81d
 static void write_buffers_queue_free(Ring *write_queue)
e2c81d
@@ -116,9 +118,11 @@ static void spice_char_device_write_buffer_pool_add(SpiceCharDeviceState *dev,
e2c81d
         buf->origin = WRITE_BUFFER_ORIGIN_NONE;
e2c81d
         buf->client = NULL;
e2c81d
         ring_add(&dev->write_bufs_pool, &buf->link);
e2c81d
-    } else {
e2c81d
-        --buf->refs;
e2c81d
+        return;
e2c81d
     }
e2c81d
+
e2c81d
+    /* Buffer still being used - just unref for the caller */
e2c81d
+    spice_char_device_write_buffer_unref(buf);
e2c81d
 }
e2c81d
 
e2c81d
 static void spice_char_device_client_send_queue_free(SpiceCharDeviceState *dev,
e2c81d
@@ -581,6 +585,15 @@ static SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_ref(SpiceCharD
e2c81d
     return write_buf;
e2c81d
 }
e2c81d
 
e2c81d
+static void spice_char_device_write_buffer_unref(SpiceCharDeviceWriteBuffer *write_buf)
e2c81d
+{
e2c81d
+    spice_assert(write_buf);
e2c81d
+
e2c81d
+    write_buf->refs--;
e2c81d
+    if (write_buf->refs == 0)
e2c81d
+        spice_char_device_write_buffer_free(write_buf);
e2c81d
+}
e2c81d
+
e2c81d
 void spice_char_device_write_buffer_add(SpiceCharDeviceState *dev,
e2c81d
                                         SpiceCharDeviceWriteBuffer *write_buf)
e2c81d
 {
e2c81d
@@ -607,8 +620,7 @@ void spice_char_device_write_buffer_release(SpiceCharDeviceState *dev,
e2c81d
     spice_assert(!ring_item_is_linked(&write_buf->link));
e2c81d
     if (!dev) {
e2c81d
         spice_printerr("no device. write buffer is freed");
e2c81d
-        free(write_buf->buf);
e2c81d
-        free(write_buf);
e2c81d
+        spice_char_device_write_buffer_free(write_buf);
e2c81d
         return;
e2c81d
     }
e2c81d
 
e2c81d
@@ -715,9 +727,7 @@ void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
e2c81d
     }
e2c81d
     write_buffers_queue_free(&char_dev->write_queue);
e2c81d
     write_buffers_queue_free(&char_dev->write_bufs_pool);
e2c81d
-    if (char_dev->cur_write_buf) {
e2c81d
-        spice_char_device_write_buffer_free(char_dev->cur_write_buf);
e2c81d
-    }
e2c81d
+    spice_char_device_write_buffer_free(char_dev->cur_write_buf);
e2c81d
 
e2c81d
     while (!ring_is_empty(&char_dev->clients)) {
e2c81d
         RingItem *item = ring_get_tail(&char_dev->clients);
e2c81d
@@ -883,7 +893,7 @@ static void migrate_data_marshaller_write_buffer_free(uint8_t *data, void *opaqu
e2c81d
 {
e2c81d
     SpiceCharDeviceWriteBuffer *write_buf = (SpiceCharDeviceWriteBuffer *)opaque;
e2c81d
 
e2c81d
-    spice_char_device_write_buffer_free(write_buf);
e2c81d
+    spice_char_device_write_buffer_unref(write_buf);
e2c81d
 }
e2c81d
 
e2c81d
 void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,