[Spice-devel] [PATCH 01/16] UpgradeItem: use base PipeItem for refcounting
Frediano Ziglio
fziglio at redhat.com
Wed Apr 20 08:18:53 UTC 2016
>
> 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;
Here a display channel is enough I think.
> 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);
I'm still pondering this.
My initial question was mainly a question (even to me) than a
proposal. Here the problem is that this can create a circular
reference counting. The problem is quite hidden by the fact that
we don't still have a way to free part of our stuff (DisplayChannel
is one). This make hard to verify this, I should have pushed the
inclusion of my cleanup branch when was refused.
Jonathon... did you test for leaks?
> + 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;
Frediano
More information about the Spice-devel
mailing list