[Spice-devel] [PATCH 01/18] worker: move more free_glz_drawable
Frediano Ziglio
fziglio at redhat.com
Fri Nov 20 07:37:54 PST 2015
>
> On Fri, 2015-11-20 at 11:17 +0000, Frediano Ziglio wrote:
> > From: Marc-André Lureau <marcandre.lureau at gmail.com>
> >
> > Acked-by: Fabiano FidĂȘncio <fidencio at redhat.com>
>
> ^^^^^^^^^^^
>
>
> Do we need further review on this? Were there changes?
>
>
>
Yes, sorry, already pushed.
I did some additional checks, patches was not looking just some move..
but it was!
Frediano
>
> > ---
> > server/dcc-encoders.c | 55 ++++++++++++++++++++++++++++++++++++++
> > server/dcc-encoders.h | 7 +++--
> > server/display-channel.c | 22 +++++++++++----
> > server/display-channel.h | 1 +
> > server/red_worker.c | 69
> > -----------------------------------------------
> > -
> > 5 files changed, 78 insertions(+), 76 deletions(-)
> >
> > diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
> > index e2e25e5..e39697a 100644
> > --- a/server/dcc-encoders.c
> > +++ b/server/dcc-encoders.c
> > @@ -473,6 +473,39 @@ void
> > dcc_free_glz_drawable_instance(DisplayChannelClient
> > *dcc,
> > }
> > }
> >
> > +/*
> > + * Releases all the instances of the drawable from the dictionary and the
> > display channel client.
> > + * The release of the last instance will also release the drawable itself
> > and
> > the qxl drawable
> > + * if possible.
> > + * NOTE - the caller should prevent encoding using the dictionary during
> > this
> > operation
> > + */
> > +void dcc_free_glz_drawable(DisplayChannelClient *dcc, RedGlzDrawable
> > *drawable)
> > +{
> > + RingItem *head_instance = ring_get_head(&drawable->instances);
> > + int cont = (head_instance != NULL);
> > +
> > + while (cont) {
> > + if (drawable->instances_count == 1) {
> > + /* Last instance: dcc_free_glz_drawable_instance will free the
> > drawable */
> > + cont = FALSE;
> > + }
> > + GlzDrawableInstanceItem *instance =
> > SPICE_CONTAINEROF(head_instance,
> > +
> > GlzDrawableInstanceItem,
> > + glz_link);
> > + if (!ring_item_is_linked(&instance->free_link)) {
> > + // the instance didn't get out from window yet
> > + glz_enc_dictionary_remove_image(dcc->glz_dict->dict,
> > + instance->context,
> > + &dcc->glz_data.usr);
> > + }
> > + dcc_free_glz_drawable_instance(dcc, instance);
> > +
> > + if (cont) {
> > + head_instance = ring_get_head(&drawable->instances);
> > + }
> > + }
> > +}
> > +
> > void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc)
> > {
> > RingItem *ring_link;
> > @@ -490,6 +523,28 @@ void
> > dcc_free_glz_drawables_to_free(DisplayChannelClient*
> > dcc)
> > pthread_mutex_unlock(&dcc->glz_drawables_inst_to_free_lock);
> > }
> >
> > +/* Clear all lz drawables - enforce their removal from the global
> > dictionary.
> > + NOTE - prevents encoding using the dictionary during the operation*/
> > +void dcc_free_glz_drawables(DisplayChannelClient *dcc)
> > +{
> > + RingItem *ring_link;
> > + GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
> > +
> > + if (!glz_dict) {
> > + return;
> > + }
> > +
> > + // assure no display channel is during global lz encoding
> > + pthread_rwlock_wrlock(&glz_dict->encode_lock);
> > + while ((ring_link = ring_get_head(&dcc->glz_drawables))) {
> > + RedGlzDrawable *drawable = SPICE_CONTAINEROF(ring_link,
> > RedGlzDrawable, link);
> > + // no need to lock the to_free list, since we assured no other
> > thread
> > is encoding and
> > + // thus not other thread access the to_free list of the channel
> > + dcc_free_glz_drawable(dcc, drawable);
> > + }
> > + pthread_rwlock_unlock(&glz_dict->encode_lock);
> > +}
> > +
> > void dcc_freeze_glz(DisplayChannelClient *dcc)
> > {
> > pthread_rwlock_wrlock(&dcc->glz_dict->encode_lock);
> > diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
> > index 5ae15ba..8c769df 100644
> > --- a/server/dcc-encoders.h
> > +++ b/server/dcc-encoders.h
> > @@ -34,10 +34,15 @@
> >
> > typedef struct RedCompressBuf RedCompressBuf;
> > typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
> > +typedef struct RedGlzDrawable RedGlzDrawable;
> > +
> >
> > void dcc_encoders_init
> > (DisplayChannelClient *dcc);
> > void dcc_free_glz_drawable_instance
> > (DisplayChannelClient *dcc,
> >
> > GlzDrawableInstanceItem *item);
> > +void dcc_free_glz_drawable
> > (DisplayChannelClient *dcc,
> > +
> > RedGlzDrawable
> > *drawable);
> > +void dcc_free_glz_drawables
> > (DisplayChannelClient *dcc);
> > void dcc_free_glz_drawables_to_free
> > (DisplayChannelClient* dcc);
> > void dcc_freeze_glz
> > (DisplayChannelClient *dcc);
> >
> > @@ -125,8 +130,6 @@ typedef struct {
> >
> > #define MAX_GLZ_DRAWABLE_INSTANCES 2
> >
> > -typedef struct RedGlzDrawable RedGlzDrawable;
> > -
> > /* for each qxl drawable, there may be several instances of lz drawables
> > */
> > /* TODO - reuse this stuff for the top level. I just added a second level
> > of
> > multiplicity
> > * at the Drawable by keeping a ring, so:
> > diff --git a/server/display-channel.c b/server/display-channel.c
> > index 3b7a016..d455a0d 100644
> > --- a/server/display-channel.c
> > +++ b/server/display-channel.c
> > @@ -850,14 +850,26 @@ void
> > display_channel_flush_all_surfaces(DisplayChannel
> > *display)
> > }
> > }
> >
> > -static void rcc_free_glz_drawables_to_free(RedChannelClient *rcc)
> > +void display_channel_free_glz_drawables_to_free(DisplayChannel *display)
> > {
> > - DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + RingItem *link, *next;
> > + DisplayChannelClient *dcc;
> >
> > - dcc_free_glz_drawables_to_free(dcc);
> > + spice_return_if_fail(display);
> > +
> > + DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display)) {
> > + dcc_free_glz_drawables_to_free(dcc);
> > + }
> > }
> >
> > -void display_channel_free_glz_drawables_to_free(DisplayChannel *display)
> > +void display_channel_free_glz_drawables(DisplayChannel *display)
> > {
> > - red_channel_apply_clients(RED_CHANNEL(display),
> > rcc_free_glz_drawables_to_free);
> > + RingItem *link, *next;
> > + DisplayChannelClient *dcc;
> > +
> > + spice_return_if_fail(display);
> > +
> > + DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display)) {
> > + dcc_free_glz_drawables(dcc);
> > + }
> > }
> > diff --git a/server/display-channel.h b/server/display-channel.h
> > index d47abf7..bad61d1 100644
> > --- a/server/display-channel.h
> > +++ b/server/display-channel.h
> > @@ -277,6 +277,7 @@ void
> > display_channel_current_flush
> > (DisplayCha
> > int display_channel_wait_for_migrate_data
> > (DisplayChannel *display);
> > void display_channel_flush_all_surfaces
> > (DisplayChannel *display);
> > void
> > display_channel_free_glz_drawables_to_free(DisplayChannel *display);
> > +void display_channel_free_glz_drawables
> > (DisplayChannel *display);
> >
> > static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
> > {
> > diff --git a/server/red_worker.c b/server/red_worker.c
> > index 6d974d6..1963b0c 100644
> > --- a/server/red_worker.c
> > +++ b/server/red_worker.c
> > @@ -183,7 +183,6 @@ static void red_update_area_till(DisplayChannel
> > *display,
> > const SpiceRect *area,
> > static inline void display_begin_send_message(RedChannelClient *rcc);
> > static void dcc_release_glz(DisplayChannelClient *dcc);
> > static int
> > red_display_free_some_independent_glz_drawables(DisplayChannelClient *dcc);
> > -static void dcc_free_glz_drawable(DisplayChannelClient *dcc,
> > RedGlzDrawable
> > *drawable);
> > static void
> > display_channel_client_release_item_before_push(DisplayChannelClient *dcc,
> > PipeItem
> > *item);
> > static void
> > display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
> > @@ -1988,74 +1987,6 @@ static void fill_base(SpiceMarshaller
> > *base_marshaller,
> > Drawable *drawable)
> > }
> >
> > /*
> > - * Releases all the instances of the drawable from the dictionary and the
> > display channel client.
> > - * The release of the last instance will also release the drawable itself
> > and
> > the qxl drawable
> > - * if possible.
> > - * NOTE - the caller should prevent encoding using the dictionary during
> > this
> > operation
> > - */
> > -static void dcc_free_glz_drawable(DisplayChannelClient *dcc,
> > RedGlzDrawable
> > *drawable)
> > -{
> > - RingItem *head_instance = ring_get_head(&drawable->instances);
> > - int cont = (head_instance != NULL);
> > -
> > - while (cont) {
> > - if (drawable->instances_count == 1) {
> > - /* Last instance: dcc_free_glz_drawable_instance will free the
> > drawable */
> > - cont = FALSE;
> > - }
> > - GlzDrawableInstanceItem *instance =
> > SPICE_CONTAINEROF(head_instance,
> > -
> > GlzDrawableInstanceItem,
> > - glz_link);
> > - if (!ring_item_is_linked(&instance->free_link)) {
> > - // the instance didn't get out from window yet
> > - glz_enc_dictionary_remove_image(dcc->glz_dict->dict,
> > - instance->context,
> > - &dcc->glz_data.usr);
> > - }
> > - dcc_free_glz_drawable_instance(dcc, instance);
> > -
> > - if (cont) {
> > - head_instance = ring_get_head(&drawable->instances);
> > - }
> > - }
> > -}
> > -
> > -/* Clear all lz drawables - enforce their removal from the global
> > dictionary.
> > - NOTE - prevents encoding using the dictionary during the operation*/
> > -static void dcc_free_glz_drawables(DisplayChannelClient *dcc)
> > -{
> > - RingItem *ring_link;
> > - GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
> > -
> > - if (!glz_dict) {
> > - return;
> > - }
> > -
> > - // assure no display channel is during global lz encoding
> > - pthread_rwlock_wrlock(&glz_dict->encode_lock);
> > - while ((ring_link = ring_get_head(&dcc->glz_drawables))) {
> > - RedGlzDrawable *drawable = SPICE_CONTAINEROF(ring_link,
> > RedGlzDrawable, link);
> > - // no need to lock the to_free list, since we assured no other
> > thread
> > is encoding and
> > - // thus not other thread access the to_free list of the channel
> > - dcc_free_glz_drawable(dcc, drawable);
> > - }
> > - pthread_rwlock_unlock(&glz_dict->encode_lock);
> > -}
> > -
> > -static void display_channel_free_glz_drawables(DisplayChannel
> > *display_channel)
> > -{
> > - RingItem *link, *next;
> > - DisplayChannelClient *dcc;
> > -
> > - if (!display_channel) {
> > - return;
> > - }
> > - DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel)) {
> > - dcc_free_glz_drawables(dcc);
> > - }
> > -}
> > -
> > -/*
> > * Remove from the global lz dictionary some glz_drawables that have no
> > reference to
> > * Drawable (their qxl drawables are released too).
> > * NOTE - the caller should prevent encoding using the dictionary during
> > the
> > operation
>
More information about the Spice-devel
mailing list