[Spice-devel] [PATCH] UpgradeItem: use base PipeItem for refcounting
Frediano Ziglio
fziglio at redhat.com
Thu Apr 21 14:30:17 UTC 2016
>
> On Thu, 2016-04-21 at 12:41 +0100, Frediano Ziglio wrote:
> > From: Jonathon Jongsma <jjongsma at redhat.com>
> >
> > 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.
> > ---
> > server/dcc.c | 18 +-----------------
> > server/display-channel.c | 4 +---
> > server/display-channel.h | 7 ++++++-
> > server/stream.c | 15 +++++++++++++--
> > 4 files changed, 21 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..00e8a53 100644
> > --- a/server/display-channel.h
> > +++ b/server/display-channel.h
> > @@ -244,7 +244,12 @@ typedef struct SurfaceDestroyItem {
> >
> > typedef struct UpgradeItem {
> > PipeItem base;
> > - int refs;
> > + /**
> > + * Pointer to the display from which the drawable is allocated.
> > + * This pointer is safe to be retained as DisplayChannel
> > + * lifespan is bigger than all drawables.
> > + */
> > + DisplayChannel *display;
>
> OK, that seems reasonable to me with minor comment change: s/bigger/longer/
>
> Although now I'm wondering if we shouldn't just modify Drawable to store the
> DisplayChannel* instead. And then change
>
> display_channel_drawable_unref(DisplayChannel*, Drawable*)
> {
> /* do stuff */
> }
>
> to
>
> drawable_unref(Drawable*)
> {
> DisplayChannel *display = drawable->display;
> /* do stuff */
> }
>
Make sense too. More aggressive (more work to do).
If you want to try I approve the idea.
> > Drawable *drawable;
> > SpiceClipRects *rects;
> > } UpgradeItem;
> > diff --git a/server/stream.c b/server/stream.c
> > index ae37a62..f8d0abe 100644
> > --- a/server/stream.c
> > +++ b/server/stream.c
> > @@ -758,6 +758,16 @@ void stream_agent_stop(StreamAgent *agent)
> > }
> > }
> >
> > +static void upgrade_item_free(UpgradeItem *item)
> > +{
> > + g_return_if_fail(item != NULL);
> > + g_return_if_fail(item->base.refcount != 0);
> > +
> > + display_channel_drawable_unref(item->display, item->drawable);
> > + free(item->rects);
> > + 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 +808,11 @@ 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->display = display;
> > 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