[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