[Spice-devel] [PATCH spice-server 07/10] red-channel-client: Avoid weird memory references using MarkerPipeItem
Frediano Ziglio
fziglio at redhat.com
Tue Sep 12 08:15:15 UTC 2017
>
> On Mon, Sep 11, 2017 at 11:15:44AM +0100, Frediano Ziglio wrote:
> > Instead of having MarkerPipeItem pointing to a variable on an external
> > stuff with the possibility to forget to reset it or having possibly
> > dangling pointers use reference counting to keep the item and
> > mark the item when sent.
>
> Look good to me, I would have added some more details in the log (that
> this stores a reference to an external variable because we need to know
> its value after the item has been processed and freed), this makes it
> easier to understand why you want reference counting.
>
> Christophe
>
How does it sound adding:
"Storing a pointer to an external variable was used to be able to use
this variable after the object was freed."
?
Frediano
> >
> > Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> > ---
> > server/red-channel-client.c | 30 +++++++++++-------------------
> > 1 file changed, 11 insertions(+), 19 deletions(-)
> >
> > diff --git a/server/red-channel-client.c b/server/red-channel-client.c
> > index 34202c492..de3ac27cb 100644
> > --- a/server/red-channel-client.c
> > +++ b/server/red-channel-client.c
> > @@ -218,7 +218,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)
> > @@ -613,6 +613,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);
> > @@ -1757,23 +1758,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;
> > - }
> > - 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");
> >
> > @@ -1785,10 +1776,9 @@ bool
> > red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
> >
> > MarkerPipeItem *mark_item = spice_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)) {
> > @@ -1797,7 +1787,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);
> > @@ -1805,9 +1795,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 {
More information about the Spice-devel
mailing list