[Spice-devel] [PATCH 05/12] server: inputs_channel: use red_channel

Hans de Goede hdegoede at redhat.com
Mon Dec 6 03:36:57 PST 2010


Hi,

See comments inline.

On 12/06/2010 11:49 AM, Alon Levy wrote:
> ---
>   server/inputs_channel.c |  406 ++++++++++++++--------------------------------
>   1 files changed, 124 insertions(+), 282 deletions(-)
>
> diff --git a/server/inputs_channel.c b/server/inputs_channel.c
> index f3e71f3..2d76d03 100644
> --- a/server/inputs_channel.c
> +++ b/server/inputs_channel.c

<snip>

> @@ -153,132 +141,22 @@ const VDAgentMouseState *inputs_get_mouse_state(void)
>       return&inputs_channel->mouse_state;
>   }
>
> -static int handle_incoming(RedsStreamContext *peer, IncomingHandler *handler)
> +static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannel *channel, SpiceDataHeader *msg_header)
>   {

<snip lots of - lines>

> +    InputsChannel *inputs_channel = SPICE_CONTAINEROF(channel, InputsChannel, base);
> +
> +    return inputs_channel->recv_buf;
>   }
>

Hmm, does red_channel guarantee that this function will only get called once? IOW will
red_channel never call this twice and expect to get 2 different buffers then ?

Also how does red_channel now the size of the buffer? I assume the size of the buffer
is supposed to be determined by the alloc function by checking the msg_header ?

Should we then not at least verify here that the static buffer is large enough ?

<snip lots of good stuff (mostly - lines)>

> -static int marshaller_outgoing_write(SpiceMarshaller *m,
> -                                     InputsChannel *state)
> +static void inputs_channel_release_pipe_item(RedChannel *channel,
> +    PipeItem *base, int item_pushed)
>   {
> -    SpiceDataHeader *header = (SpiceDataHeader *)spice_marshaller_get_ptr(m);
> +    // All PipeItems we push are InputsPipeItem
> +    InputsPipeItem *item = (InputsPipeItem*)base;
> +
> +    if (item->data) {
> +        free(item->data);
> +    }
> +}
> +

Hmm, we are responsible for allocating the item itself too in inputs_pipe_item_new
should we not release it then (just checking) ?

> +static void inputs_channel_send_item(RedChannel *channel, PipeItem *base)
> +{
> +    InputsPipeItem *item = SPICE_CONTAINEROF(base, InputsPipeItem, base);
> +    SpiceMarshaller *m = item->m;
>       uint8_t *data;
>       size_t len;
>       int free_data;
>
> +    red_channel_reset_send_data(channel);
> +    red_channel_init_send_data(channel, base->type, base);
>       spice_marshaller_flush(m);
> -    header->size = spice_marshaller_get_total_size(m) - sizeof(SpiceDataHeader);
> -
> +    // TODO: use spice_marshaller_fill_iovec. Right now we are doing something stupid,
> +    // namely copying twice. See reds.c.
>       data = spice_marshaller_linearize(m, 0,&len,&free_data);
> -
> -    if (outgoing_write(state->peer,&state->out_handler, data, len) != OUTGOING_OK) {
> -        return FALSE;
> -    }
> -
> -    if (free_data) {
> -        free(data);
> +    item->data = (free_data&&  len>  0) ? data : NULL;
> +    if (len>  0) {
> +        red_channel_add_buf(channel, data, len);
>       }
> -
> -    return TRUE;
> +    spice_marshaller_destroy(m);
> +    red_channel_begin_send_message(channel);
>   }
>

Hmm (again), so if spice_marshaller_linearize indicates the data should be free-ed by
the caller, we do so when the item gets destroyed (iow not right now), this makes me
assume that red_channel_add_buf does not copy the data, but merely stores a reference
to it. So what if spice_marshaller_linearize() does not say the caller should free
the buffer (iow it is returning some internal buffer). Won't that buffer get destroyed
then as soon as spice_marshaller_destroy gets called, iow before the channel is done
with it.

Note if my assumption is wrong and red_channel_add_buf does copy the data, why delay
freeing the data until the item gets destroyed and not free the data immediately after
the red_channel_add_buf call ?

<snip more stuff>

>   static void inputs_migrate(Channel *channel)
>   {
> -    InputsChannel *state = (InputsChannel *)channel->data;
> -    SpiceMarshaller *m;
> +    InputsPipeItem *pipe_item = inputs_pipe_item_new(inputs_channel, PIPE_ITEM_MIGRATE);
> +    SpiceMarshaller *m = pipe_item->m;
>       SpiceMsgMigrate migrate;
>
> -    m = marshaller_new_for_outgoing(state, SPICE_MSG_MIGRATE);
> -
> +    ASSERT(inputs_channel == (InputsChannel *)channel->data);
>       migrate.flags = 0;
>       spice_marshall_msg_migrate(m,&migrate);
> -
> -    if (!marshaller_outgoing_write(m, state)) {
> -        red_printf("write failed");
> -    }
> -    spice_marshaller_destroy(m);
> +    red_channel_pipe_add(&inputs_channel->base,&pipe_item->base);
>   }
>

Question, have you tested migration with these patches ?

<snip more stuff>


Phew all done :)

I'll review the rest of your patches after my lunch break. I'll also try
to remember to start up my irc client then unlike this morning :)


Regards,

Hans


More information about the Spice-devel mailing list