summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2011-08-02 11:01:16 +0300
committerAlon Levy <alevy@redhat.com>2011-08-23 18:04:10 +0300
commitbed8c9d4f6e62165452fe1082492eb43d2c7c5bc (patch)
treee6b4a21bc6b7fcfddc36d6333d77d3c974062ae0 /server
parent52bff67935f453f8cf7ccaa3add41f8f122cf4eb (diff)
downloadspice-bed8c9d4f6e62165452fe1082492eb43d2c7c5bc.tar.gz
spice-bed8c9d4f6e62165452fe1082492eb43d2c7c5bc.tar.xz
spice-bed8c9d4f6e62165452fe1082492eb43d2c7c5bc.zip
server/red_worker.c: fix CursorPipeItem leak
CursorPipeItems and their corresponding cursor_item were not freed when they were removed from the pipe without sending them. In addition cursor_channel_hold_pipe_item used wrong conversion to (CursorItem*) for a (CursorPipeItem*).
Diffstat (limited to 'server')
-rw-r--r--server/red_worker.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/server/red_worker.c b/server/red_worker.c
index 29881642..7593ce91 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -320,6 +320,7 @@ typedef struct CursorItem {
typedef struct CursorPipeItem {
PipeItem base;
CursorItem *cursor_item;
+ int refs;
} CursorPipeItem;
typedef struct LocalCursor {
@@ -4519,16 +4520,38 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
return cursor_item;
}
+static CursorPipeItem *ref_cursor_pipe_item(CursorPipeItem *item)
+{
+ ASSERT(item);
+ item->refs++;
+ return item;
+}
+
static PipeItem *new_cursor_pipe_item(RedChannelClient *rcc, void *data, int num)
{
CursorPipeItem *item = spice_malloc0(sizeof(CursorPipeItem));
red_channel_pipe_item_init(rcc->channel, &item->base, PIPE_ITEM_TYPE_CURSOR);
+ item->refs = 1;
item->cursor_item = data;
item->cursor_item->refs++;
return &item->base;
}
+static void put_cursor_pipe_item(CursorChannelClient *ccc, CursorPipeItem *pipe_item)
+{
+ ASSERT(pipe_item);
+
+ if (--pipe_item->refs) {
+ return;
+ }
+
+ ASSERT(!pipe_item_is_linked(&pipe_item->base));
+
+ red_release_cursor(ccc->common.worker, pipe_item->cursor_item);
+ free(pipe_item);
+}
+
static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint32_t group_id)
{
CursorItem *cursor_item;
@@ -9550,6 +9573,8 @@ static void display_channel_client_release_item_after_push(DisplayChannelClient
}
}
+// TODO: share code between before/after_push since most of the items need the same
+// release
static void display_channel_client_release_item_before_push(DisplayChannelClient *dcc,
PipeItem *item)
{
@@ -9813,16 +9838,23 @@ static void on_new_cursor_channel(RedWorker *worker, RedChannelClient *rcc)
static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
{
+ CursorPipeItem *cursor_pipe_item;
ASSERT(item);
- ((CursorItem *)item)->refs++;
+ cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
+ ref_cursor_pipe_item(cursor_pipe_item);
}
+// TODO: share code between before/after_push since most of the items need the same
+// release
static void cursor_channel_client_release_item_before_push(CursorChannelClient *ccc,
PipeItem *item)
{
switch (item->type) {
- case PIPE_ITEM_TYPE_CURSOR:
+ case PIPE_ITEM_TYPE_CURSOR: {
+ CursorPipeItem *cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
+ put_cursor_pipe_item(ccc, cursor_pipe_item);
break;
+ }
case PIPE_ITEM_TYPE_INVAL_ONE:
case PIPE_ITEM_TYPE_VERB:
case PIPE_ITEM_TYPE_MIGRATE:
@@ -9841,8 +9873,7 @@ static void cursor_channel_client_release_item_after_push(CursorChannelClient *c
switch (item->type) {
case PIPE_ITEM_TYPE_CURSOR: {
CursorPipeItem *cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
- red_release_cursor(ccc->common.worker, cursor_pipe_item->cursor_item);
- free(cursor_pipe_item);
+ put_cursor_pipe_item(ccc, cursor_pipe_item);
break;
}
default: