|
|
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,
|