[Spice-devel] [PATCH 01/18] worker: move more free_glz_drawable
Jonathon Jongsma
jjongsma at redhat.com
Fri Nov 20 06:59:52 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?
> ---
> 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