summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/main_channel.c32
-rw-r--r--server/main_channel.h2
-rw-r--r--server/reds.c33
-rw-r--r--server/reds.h3
4 files changed, 46 insertions, 24 deletions
diff --git a/server/main_channel.c b/server/main_channel.c
index ace24ff6..ce467f83 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 afff3139..7f620bba 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 26d6f89f..9da89580 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 1c59e689..674052a8 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