From 92d9b782bd0754083f79a04a9e9edc38339c0cc4 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Thu, 13 Feb 2014 16:56:59 +0100 Subject: worker: simplify RedCompressBuf Make sure an allocated buffer is correctly referenced by the marshaller, and can't be free and reused by mistake. Simplify the code by using GSlice Acked-by: Jonathon Jongsma --- server/display-channel.h | 3 -- server/red_worker.c | 116 ++++++++++++----------------------------------- 2 files changed, 30 insertions(+), 89 deletions(-) diff --git a/server/display-channel.h b/server/display-channel.h index b207e245..5e11d0e3 100644 --- a/server/display-channel.h +++ b/server/display-channel.h @@ -81,7 +81,6 @@ struct RedCompressBuf { uint8_t bytes[RED_COMPRESS_BUF_SIZE]; uint32_t words[RED_COMPRESS_BUF_SIZE / 4]; } buf; - RedCompressBuf *next; RedCompressBuf *send_next; }; @@ -189,8 +188,6 @@ struct DisplayChannelClient { uint32_t stream_outbuf_size; uint8_t *stream_outbuf; // caution stream buffer is also used as compress bufs!!! - RedCompressBuf *used_compress_bufs; - FreeList free_list; uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS]; int num_pixmap_cache_items; diff --git a/server/red_worker.c b/server/red_worker.c index d567a0ea..af269f6b 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -2708,16 +2708,32 @@ static void red_push_surface_image(DisplayChannelClient *dcc, int surface_id) red_channel_client_push(RED_CHANNEL_CLIENT(dcc)); } +static RedCompressBuf *compress_buf_new(void) +{ + return g_slice_new(RedCompressBuf); +} + +static inline void compress_buf_free(RedCompressBuf *buf) +{ + g_slice_free(RedCompressBuf, buf); +} + +static void marshaller_compress_buf_free(uint8_t *data, void *opaque) +{ + compress_buf_free((RedCompressBuf *) opaque); +} + static void marshaller_add_compressed(SpiceMarshaller *m, RedCompressBuf *comp_buf, size_t size) { size_t max = size; size_t now; do { - spice_assert(comp_buf); + spice_return_if_fail(comp_buf); now = MIN(sizeof(comp_buf->buf), max); max -= now; - spice_marshaller_add_ref(m, comp_buf->buf.bytes, now); + spice_marshaller_add_ref_full(m, comp_buf->buf.bytes, now, + marshaller_compress_buf_free, comp_buf); comp_buf = comp_buf->send_next; } while (max); } @@ -2752,66 +2768,6 @@ static inline void fill_palette(DisplayChannelClient *dcc, } } -static inline RedCompressBuf *red_display_alloc_compress_buf(DisplayChannelClient *dcc) -{ - DisplayChannel *display_channel = DCC_TO_DC(dcc); - RedCompressBuf *ret; - - if (display_channel->free_compress_bufs) { - ret = display_channel->free_compress_bufs; - display_channel->free_compress_bufs = ret->next; - } else { - ret = spice_new(RedCompressBuf, 1); - } - - ret->next = dcc->send_data.used_compress_bufs; - dcc->send_data.used_compress_bufs = ret; - return ret; -} - -static inline void __red_display_free_compress_buf(DisplayChannel *dc, - RedCompressBuf *buf) -{ - buf->next = dc->free_compress_bufs; - dc->free_compress_bufs = buf; -} - -static void red_display_free_compress_buf(DisplayChannelClient *dcc, - RedCompressBuf *buf) -{ - DisplayChannel *display_channel = DCC_TO_DC(dcc); - RedCompressBuf **curr_used = &dcc->send_data.used_compress_bufs; - - for (;;) { - spice_assert(*curr_used); - if (*curr_used == buf) { - *curr_used = buf->next; - break; - } - curr_used = &(*curr_used)->next; - } - __red_display_free_compress_buf(display_channel, buf); -} - -static void red_display_reset_compress_buf(DisplayChannelClient *dcc) -{ - while (dcc->send_data.used_compress_bufs) { - RedCompressBuf *buf = dcc->send_data.used_compress_bufs; - dcc->send_data.used_compress_bufs = buf->next; - __red_display_free_compress_buf(DCC_TO_DC(dcc), buf); - } -} - -static void red_display_destroy_compress_bufs(DisplayChannel *display_channel) -{ - spice_assert(!red_channel_is_connected(RED_CHANNEL(display_channel))); - while (display_channel->free_compress_bufs) { - RedCompressBuf *buf = display_channel->free_compress_bufs; - display_channel->free_compress_bufs = buf->next; - free(buf); - } -} - /****************************************************** * Global lz red drawables routines *******************************************************/ @@ -3139,9 +3095,7 @@ static int encoder_usr_more_space(EncoderData *enc_data, uint8_t **io_ptr) { RedCompressBuf *buf; - if (!(buf = red_display_alloc_compress_buf(enc_data->dcc))) { - return 0; - } + buf = compress_buf_new(); enc_data->bufs_tail->send_next = buf; enc_data->bufs_tail = buf; buf->send_next = NULL; @@ -3401,7 +3355,7 @@ static inline int red_glz_compress_image(DisplayChannelClient *dcc, int glz_size; int zlib_size; - glz_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + glz_data->data.bufs_tail = compress_buf_new(); glz_data->data.bufs_head = glz_data->data.bufs_tail; if (!glz_data->data.bufs_head) { @@ -3437,7 +3391,7 @@ static inline int red_glz_compress_image(DisplayChannelClient *dcc, #endif zlib_data = &worker->zlib_data; - zlib_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + zlib_data->data.bufs_tail = compress_buf_new(); zlib_data->data.bufs_head = zlib_data->data.bufs_tail; if (!zlib_data->data.bufs_head) { @@ -3460,7 +3414,7 @@ static inline int red_glz_compress_image(DisplayChannelClient *dcc, while (zlib_data->data.bufs_head) { RedCompressBuf *buf = zlib_data->data.bufs_head; zlib_data->data.bufs_head = buf->send_next; - red_display_free_compress_buf(dcc, buf); + compress_buf_free(buf); } goto glz; } @@ -3499,7 +3453,7 @@ static inline int red_lz_compress_image(DisplayChannelClient *dcc, stat_time_t start_time = stat_now(DCC_TO_DC(dcc)->lz_stat.clock); #endif - lz_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + lz_data->data.bufs_tail = compress_buf_new(); lz_data->data.bufs_head = lz_data->data.bufs_tail; if (!lz_data->data.bufs_head) { @@ -3513,7 +3467,7 @@ static inline int red_lz_compress_image(DisplayChannelClient *dcc, while (lz_data->data.bufs_head) { RedCompressBuf *buf = lz_data->data.bufs_head; lz_data->data.bufs_head = buf->send_next; - red_display_free_compress_buf(dcc, buf); + compress_buf_free(buf); } return FALSE; } @@ -3602,7 +3556,7 @@ static int red_jpeg_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, return FALSE; } - jpeg_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + jpeg_data->data.bufs_tail = compress_buf_new(); jpeg_data->data.bufs_head = jpeg_data->data.bufs_tail; if (!jpeg_data->data.bufs_head) { @@ -3617,7 +3571,7 @@ static int red_jpeg_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, while (jpeg_data->data.bufs_head) { RedCompressBuf *buf = jpeg_data->data.bufs_head; jpeg_data->data.bufs_head = buf->send_next; - red_display_free_compress_buf(dcc, buf); + compress_buf_free(buf); } return FALSE; } @@ -3719,7 +3673,7 @@ static int red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, stat_time_t start_time = stat_now(worker->clockid); #endif - lz4_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + lz4_data->data.bufs_tail = compress_buf_new(); lz4_data->data.bufs_head = lz4_data->data.bufs_tail; if (!lz4_data->data.bufs_head) { @@ -3734,7 +3688,7 @@ static int red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage *dest, while (lz4_data->data.bufs_head) { RedCompressBuf *buf = lz4_data->data.bufs_head; lz4_data->data.bufs_head = buf->send_next; - red_display_free_compress_buf(dcc, buf); + compress_buf_free(buf); } return FALSE; } @@ -3802,13 +3756,8 @@ static inline int red_quic_compress_image(DisplayChannelClient *dcc, SpiceImage return FALSE; } - quic_data->data.bufs_tail = red_display_alloc_compress_buf(dcc); + quic_data->data.bufs_tail = compress_buf_new(); quic_data->data.bufs_head = quic_data->data.bufs_tail; - - if (!quic_data->data.bufs_head) { - return FALSE; - } - quic_data->data.bufs_head->send_next = NULL; quic_data->data.dcc = dcc; @@ -3816,7 +3765,7 @@ static inline int red_quic_compress_image(DisplayChannelClient *dcc, SpiceImage while (quic_data->data.bufs_head) { RedCompressBuf *buf = quic_data->data.bufs_head; quic_data->data.bufs_head = buf->send_next; - red_display_free_compress_buf(dcc, buf); + compress_buf_free(buf); } return FALSE; } @@ -4298,7 +4247,6 @@ static void fill_attr(SpiceMarshaller *m, SpiceLineAttr *attr, uint32_t group_id static inline void red_display_reset_send_data(DisplayChannelClient *dcc) { - red_display_reset_compress_buf(dcc); dcc->send_data.free_list.res->count = 0; dcc->send_data.num_pixmap_cache_items = 0; memset(dcc->send_data.free_list.sync, 0, sizeof(dcc->send_data.free_list.sync)); @@ -6521,14 +6469,10 @@ static void display_channel_client_on_disconnect(RedChannelClient *rcc) red_release_glz(dcc); red_reset_palette_cache(dcc); free(dcc->send_data.stream_outbuf); - red_display_reset_compress_buf(dcc); free(dcc->send_data.free_list.res); dcc_destroy_stream_agents(dcc); // this was the last channel client - if (!red_channel_is_connected(rcc->channel)) { - red_display_destroy_compress_bufs(display); - } spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display->drawable_count, worker->red_drawable_count, worker->glz_drawable_count); -- cgit