mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-08 18:37:34 +00:00
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 <jjongsma@redhat.com>
This commit is contained in:
parent
3941d03d11
commit
92d9b782bd
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user