[Spice-devel] [PATCH spice-server 04/14] agent: Fix tokens handling in main_channel

Hans de Goede hdegoede at redhat.com
Mon Jul 2 06:06:45 PDT 2012


Looks good, ack.

On 06/27/2012 05:16 PM, Yonit Halperin wrote:
> - Allow sending tokens to a specific client.
> - Do not ignore tokens that are sent from the client to the server.
>
> The tokens support for multiple clients and for server side tokens
> is still broken in reds. It will be fixed in following patches, when
> the server-side agent code will use the SpiceCharDeviceState api.
>
> Notice that ignoring the server-side tokens didn't introduce a problem
> since both the client and the server set it to ~0.
> ---
>   server/main_channel.c |   32 +++++++++++++++++---------------
>   server/main_channel.h |    2 +-
>   server/reds.c         |   33 ++++++++++++++++++++++++++-------
>   server/reds.h         |    3 ++-
>   4 files changed, 46 insertions(+), 24 deletions(-)
>
> diff --git a/server/main_channel.c b/server/main_channel.c
> index ace24ff..ce467f8 100644
> --- a/server/main_channel.c
> +++ b/server/main_channel.c
> @@ -222,18 +222,13 @@ static PipeItem *main_ping_item_new(MainChannelClient *mcc, int size)
>       return &item->base;
>   }
>
> -typedef struct MainTokensItemInfo {
> -    uint32_t num_tokens;
> -} MainTokensItemInfo;
> -
> -static PipeItem *main_tokens_item_new(RedChannelClient *rcc, void *data, int num)
> +static PipeItem *main_agent_tokens_item_new(RedChannelClient *rcc, uint32_t num_tokens)
>   {
>       TokensPipeItem *item = spice_malloc(sizeof(TokensPipeItem));
> -    MainTokensItemInfo *init = data;
>
>       red_channel_pipe_item_init(rcc->channel, &item->base,
>                                  SPICE_MSG_MAIN_AGENT_TOKEN);
> -    item->tokens = init->num_tokens;
> +    item->tokens = num_tokens;
>       return &item->base;
>   }
>
> @@ -422,13 +417,11 @@ static void main_channel_marshall_agent_disconnected(SpiceMarshaller *m)
>       spice_marshall_msg_main_agent_disconnected(m, &disconnect);
>   }
>
> -// TODO: make this targeted (requires change to agent token accounting)
> -void main_channel_push_tokens(MainChannel *main_chan, uint32_t num_tokens)
> +void main_channel_client_push_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens)
>   {
> -    MainTokensItemInfo init = {.num_tokens = num_tokens};
> +    PipeItem *item = main_agent_tokens_item_new(&mcc->base, num_tokens);
>
> -    red_channel_pipes_new_add_push(&main_chan->base,
> -        main_tokens_item_new, &init);
> +    red_channel_client_pipe_add_push(&mcc->base, item);
>   }
>
>   static void main_channel_marshall_tokens(SpiceMarshaller *m, uint32_t num_tokens)
> @@ -828,19 +821,28 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
>       MainChannelClient *mcc = SPICE_CONTAINEROF(rcc, MainChannelClient, base);
>
>       switch (type) {
> -    case SPICE_MSGC_MAIN_AGENT_START:
> +    case SPICE_MSGC_MAIN_AGENT_START: {
> +        SpiceMsgcMainAgentStart *tokens;
> +
>           spice_printerr("agent start");
>           if (!main_chan) {
>               return FALSE;
>           }
> -        reds_on_main_agent_start();
> +        tokens = (SpiceMsgcMainAgentStart *)message;
> +        reds_on_main_agent_start(mcc, tokens->num_tokens);
>           break;
> +    }
>       case SPICE_MSGC_MAIN_AGENT_DATA: {
>           reds_on_main_agent_data(mcc, message, size);
>           break;
>       }
> -    case SPICE_MSGC_MAIN_AGENT_TOKEN:
> +    case SPICE_MSGC_MAIN_AGENT_TOKEN: {
> +        SpiceMsgcMainAgentTokens *tokens;
> +
> +        tokens = (SpiceMsgcMainAgentTokens *)message;
> +        reds_on_main_agent_tokens(mcc, tokens->num_tokens);
>           break;
> +    }
>       case SPICE_MSGC_MAIN_ATTACH_CHANNELS:
>           main_channel_push_channels(mcc);
>           break;
> diff --git a/server/main_channel.h b/server/main_channel.h
> index afff313..7f620bb 100644
> --- a/server/main_channel.h
> +++ b/server/main_channel.h
> @@ -72,7 +72,7 @@ void main_channel_close(MainChannel *main_chan); // not destroy, just socket clo
>   void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode, int is_client_mouse_allowed);
>   void main_channel_push_agent_connected(MainChannel *main_chan);
>   void main_channel_push_agent_disconnected(MainChannel *main_chan);
> -void main_channel_push_tokens(MainChannel *main_chan, uint32_t num_tokens);
> +void main_channel_client_push_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens);
>   void main_channel_push_agent_data(MainChannel *main_chan, uint8_t* data, size_t len,
>              spice_marshaller_item_free_func free_data, void *opaque);
>   void main_channel_client_start_net_test(MainChannelClient *mcc);
> diff --git a/server/reds.c b/server/reds.c
> index 26d6f89..9da8958 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -756,11 +756,13 @@ static void reds_agent_remove(void)
>       }
>   }
>
> -static void reds_push_tokens(void)
> +/* this will be fixed to handle multiple clients
> +   in following patches */
> +static void reds_push_tokens(MainChannelClient *mcc)
>   {
>       reds->agent_state.num_client_tokens += reds->agent_state.num_tokens;
>       spice_assert(reds->agent_state.num_client_tokens <= REDS_AGENT_WINDOW_SIZE);
> -    main_channel_push_tokens(reds->main_channel, reds->agent_state.num_tokens);
> +    main_channel_client_push_agent_tokens(mcc, reds->agent_state.num_tokens);
>       reds->agent_state.num_tokens = 0;
>   }
>
> @@ -998,12 +1000,14 @@ void reds_handle_agent_mouse_event(const VDAgentMouseState *mouse_state)
>       write_to_vdi_port();
>   }
>
> -static void add_token(void)
> +static void add_token(MainChannelClient *mcc)
>   {
>       VDIPortState *state = &reds->agent_state;
>
> +    /* this will be fixed to handle multiple clients
> +       in following patches */
>       if (++state->num_tokens == REDS_TOKENS_TO_SEND) {
> -        reds_push_tokens();
> +        reds_push_tokens(mcc);
>       }
>   }
>
> @@ -1012,6 +1016,7 @@ int reds_num_of_channels(void)
>       return reds ? reds->num_of_channels : 0;
>   }
>
> +
>   int reds_num_of_clients(void)
>   {
>       return reds ? reds->num_clients : 0;
> @@ -1059,7 +1064,7 @@ void reds_fill_channels(SpiceMsgChannels *channels_info)
>       }
>   }
>
> -void reds_on_main_agent_start(void)
> +void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens)
>   {
>       if (!vdagent) {
>           return;
> @@ -1067,6 +1072,14 @@ void reds_on_main_agent_start(void)
>       reds->agent_state.write_filter.discard_all = FALSE;
>   }
>
> +void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens)
> +{
> +    if (!vdagent) {
> +        return;
> +    }
> +    spice_printerr("to be implemented");
> +}
> +
>   void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
>   {
>       // TODO - use mcc (and start tracking agent data per channel. probably just move the whole
> @@ -1088,7 +1101,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
>       case AGENT_MSG_FILTER_OK:
>           break;
>       case AGENT_MSG_FILTER_DISCARD:
> -        add_token();
> +        add_token(mcc);
>           return;
>       case AGENT_MSG_FILTER_PROTO_ERROR:
>           reds_disconnect();
> @@ -3577,9 +3590,15 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
>   static void free_external_agent_buff(VDIPortBuf *in_buf)
>   {
>       VDIPortState *state = &reds->agent_state;
> +    RedClient *random_client;
>
>       ring_add(&state->external_bufs, &in_buf->link);
> -    add_token();
> +    /* this will be fixed to handle multiple clients
> +       in following patches */
> +    random_client = SPICE_CONTAINEROF(ring_get_tail(&reds->clients),
> +                                      RedClient,
> +                                      link);
> +    add_token(red_client_get_main(random_client));
>   }
>
>   static void free_internal_agent_buff(VDIPortBuf *in_buf)
> diff --git a/server/reds.h b/server/reds.h
> index 1c59e68..674052a 100644
> --- a/server/reds.h
> +++ b/server/reds.h
> @@ -145,7 +145,8 @@ void reds_update_stat_value(uint32_t value);
>
>   /* callbacks from main channel messages */
>
> -void reds_on_main_agent_start(void);
> +void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens);
> +void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens);
>   void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size);
>   void reds_on_main_migrate_connected(void); //should be called when all the clients
>                                              // are connected to the target
>



More information about the Spice-devel mailing list