mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 22:48:19 +00:00
red-channel-client: Avoid weird memory references using MarkerPipeItem
Instead of having MarkerPipeItem pointing to an external variable with the possibility to forget to reset it and have a dangling pointer, this commit takes a reference on the item to keep it alive after it was sent. This item is placed into the queue to understand when it was sent. The current implementation detects the unqueue when the item is destroyed so we currently store a pointer to an external variable in the item, this way we can use a variable which will still be alive after the item is released/destroyed. This change updates the variable (stored in the item) when we try to send the item, rather than at destruction time. The destruction happened at the end of red_channel_client_send_item(), so we don't mark item_in_pipe much earlier than before. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This commit is contained in:
parent
8a9c51bd4f
commit
b2fa6ec66c
@ -215,7 +215,7 @@ typedef struct RedEmptyMsgPipeItem {
|
||||
|
||||
typedef struct MarkerPipeItem {
|
||||
RedPipeItem base;
|
||||
gboolean *item_in_pipe;
|
||||
bool item_in_pipe;
|
||||
} MarkerPipeItem;
|
||||
|
||||
static void red_channel_client_start_ping_timer(RedChannelClient *rcc, uint32_t timeout)
|
||||
@ -610,6 +610,7 @@ static void red_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *ite
|
||||
red_channel_client_send_ping(rcc);
|
||||
break;
|
||||
case RED_PIPE_ITEM_TYPE_MARKER:
|
||||
SPICE_UPCAST(MarkerPipeItem, item)->item_in_pipe = false;
|
||||
break;
|
||||
default:
|
||||
red_channel_send_item(rcc->priv->channel, rcc, item);
|
||||
@ -1752,23 +1753,13 @@ void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_
|
||||
rcc->priv->send_data.header.set_msg_sub_list(&rcc->priv->send_data.header, sub_list);
|
||||
}
|
||||
|
||||
static void marker_pipe_item_free(RedPipeItem *base)
|
||||
{
|
||||
MarkerPipeItem *item = SPICE_UPCAST(MarkerPipeItem, base);
|
||||
|
||||
if (item->item_in_pipe) {
|
||||
*item->item_in_pipe = FALSE;
|
||||
}
|
||||
g_free(item);
|
||||
}
|
||||
|
||||
/* TODO: more evil sync stuff. anything with the word wait in it's name. */
|
||||
bool red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
|
||||
GList *item_pos,
|
||||
int64_t timeout)
|
||||
{
|
||||
uint64_t end_time;
|
||||
gboolean item_in_pipe;
|
||||
bool item_in_pipe;
|
||||
|
||||
spice_debug("trace");
|
||||
|
||||
@ -1780,10 +1771,9 @@ bool red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
|
||||
|
||||
MarkerPipeItem *mark_item = g_new0(MarkerPipeItem, 1);
|
||||
|
||||
red_pipe_item_init_full(&mark_item->base, RED_PIPE_ITEM_TYPE_MARKER,
|
||||
marker_pipe_item_free);
|
||||
item_in_pipe = TRUE;
|
||||
mark_item->item_in_pipe = &item_in_pipe;
|
||||
red_pipe_item_init(&mark_item->base, RED_PIPE_ITEM_TYPE_MARKER);
|
||||
mark_item->item_in_pipe = true;
|
||||
red_pipe_item_ref(&mark_item->base);
|
||||
red_channel_client_pipe_add_after_pos(rcc, &mark_item->base, item_pos);
|
||||
|
||||
if (red_channel_client_is_blocked(rcc)) {
|
||||
@ -1792,7 +1782,7 @@ bool red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
|
||||
}
|
||||
red_channel_client_push(rcc);
|
||||
|
||||
while (item_in_pipe &&
|
||||
while (mark_item->item_in_pipe &&
|
||||
(timeout == -1 || spice_get_monotonic_time_ns() < end_time)) {
|
||||
usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
|
||||
red_channel_client_receive(rcc);
|
||||
@ -1800,9 +1790,11 @@ bool red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
|
||||
red_channel_client_push(rcc);
|
||||
}
|
||||
|
||||
item_in_pipe = mark_item->item_in_pipe;
|
||||
red_pipe_item_unref(&mark_item->base);
|
||||
|
||||
if (item_in_pipe) {
|
||||
// still on the queue, make sure won't overwrite the stack variable
|
||||
mark_item->item_in_pipe = NULL;
|
||||
// still on the queue
|
||||
spice_warning("timeout");
|
||||
return FALSE;
|
||||
} else {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user