[Spice-devel] [PATCH 01/18] worker: move more free_glz_drawable
Frediano Ziglio
fziglio at redhat.com
Fri Nov 20 03:17:25 PST 2015
From: Marc-André Lureau <marcandre.lureau at gmail.com>
Acked-by: Fabiano FidĂȘncio <fidencio at redhat.com>
---
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
--
2.4.3
More information about the Spice-devel
mailing list