No need to re-implement refcounting in this subclass. However, I needed to add a new 'dcc' member to UpgradeItem to be able to unref properly. --- Change since last patch: take ref on dcc server/dcc.c | 18 +----------------- server/display-channel.c | 4 +--- server/display-channel.h | 2 +- server/stream.c | 18 ++++++++++++++++-- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/server/dcc.c b/server/dcc.c index 91c3f82..5193c17 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -1591,29 +1591,15 @@ int dcc_handle_migrate_data(DisplayChannelClient *dcc, uint32_t size, void *mess return TRUE; } -static void upgrade_item_unref(DisplayChannel *display, UpgradeItem *item) -{ - if (--item->refs != 0) - return; - - display_channel_drawable_unref(display, item->drawable); - free(item->rects); - free(item); -} - static void release_item_after_push(DisplayChannelClient *dcc, PipeItem *item) { - DisplayChannel *display = DCC_TO_DC(dcc); - switch (item->type) { case PIPE_ITEM_TYPE_DRAW: case PIPE_ITEM_TYPE_IMAGE: case PIPE_ITEM_TYPE_STREAM_CLIP: case PIPE_ITEM_TYPE_MONITORS_CONFIG: - pipe_item_unref(item); - break; case PIPE_ITEM_TYPE_UPGRADE: - upgrade_item_unref(display, (UpgradeItem *)item); + pipe_item_unref(item); break; case PIPE_ITEM_TYPE_GL_SCANOUT: case PIPE_ITEM_TYPE_GL_DRAW: @@ -1651,8 +1637,6 @@ static void release_item_before_push(DisplayChannelClient *dcc, PipeItem *item) } case PIPE_ITEM_TYPE_STREAM_CLIP: case PIPE_ITEM_TYPE_UPGRADE: - upgrade_item_unref(display, (UpgradeItem *)item); - break; case PIPE_ITEM_TYPE_IMAGE: case PIPE_ITEM_TYPE_MONITORS_CONFIG: pipe_item_unref(item); diff --git a/server/display-channel.c b/server/display-channel.c index 88dbc74..98b4a43 100644 --- a/server/display-channel.c +++ b/server/display-channel.c @@ -1973,10 +1973,8 @@ static void hold_item(RedChannelClient *rcc, PipeItem *item) case PIPE_ITEM_TYPE_DRAW: case PIPE_ITEM_TYPE_IMAGE: case PIPE_ITEM_TYPE_STREAM_CLIP: - pipe_item_ref(item); - break; case PIPE_ITEM_TYPE_UPGRADE: - ((UpgradeItem *)item)->refs++; + pipe_item_ref(item); break; default: spice_warn_if_reached(); diff --git a/server/display-channel.h b/server/display-channel.h index 6b053de..8944f06 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -244,7 +244,7 @@ typedef struct SurfaceDestroyItem { typedef struct UpgradeItem { PipeItem base; - int refs; + DisplayChannelClient *dcc; Drawable *drawable; SpiceClipRects *rects; } UpgradeItem; diff --git a/server/stream.c b/server/stream.c index ae37a62..80cfe2e 100644 --- a/server/stream.c +++ b/server/stream.c @@ -758,6 +758,18 @@ void stream_agent_stop(StreamAgent *agent) } } +static void upgrade_item_free(UpgradeItem *item) +{ + g_return_if_fail(item != NULL); + DisplayChannel *display = DCC_TO_DC(item->dcc); + g_return_if_fail(item->base.refcount != 0); + + display_channel_drawable_unref(display, item->drawable); + free(item->rects); + red_channel_client_unref(RED_CHANNEL_CLIENT(item->dcc)); + free(item); +} + /* * after dcc_detach_stream_gracefully is called for all the display channel clients, * detach_stream should be called. See comment (1). @@ -798,10 +810,12 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc, rect_debug(&stream->current->red_drawable->bbox); rcc = RED_CHANNEL_CLIENT(dcc); upgrade_item = spice_new(UpgradeItem, 1); - upgrade_item->refs = 1; - pipe_item_init(&upgrade_item->base, PIPE_ITEM_TYPE_UPGRADE); + pipe_item_init_full(&upgrade_item->base, PIPE_ITEM_TYPE_UPGRADE, + (GDestroyNotify)upgrade_item_free); upgrade_item->drawable = stream->current; upgrade_item->drawable->refs++; + upgrade_item->dcc = dcc; + red_channel_client_ref(RED_CHANNEL_CLIENT(upgrade_item->dcc)); n_rects = pixman_region32_n_rects(&upgrade_item->drawable->tree_item.base.rgn); upgrade_item->rects = spice_malloc_n_m(n_rects, sizeof(SpiceRect), sizeof(SpiceClipRects)); upgrade_item->rects->num_rects = n_rects; -- 2.4.11 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel