This is an intermediate patch. The next patch will actually push the buffer to the device, instead of copying it. --- server/main_channel.c | 10 +++++++++- server/reds.c | 33 +++++++++++++++++++++++++++++++++ server/reds.h | 2 ++ 3 files changed, 44 insertions(+), 1 deletions(-) diff --git a/server/main_channel.c b/server/main_channel.c index f9492b0..00a6b0f 100644 --- a/server/main_channel.c +++ b/server/main_channel.c @@ -902,8 +902,13 @@ static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, uint32_t size) { MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); + MainChannelClient *mcc = SPICE_CONTAINEROF(rcc, MainChannelClient, base); - return main_chan->recv_buf; + if (type == SPICE_MSGC_MAIN_AGENT_DATA) { + return reds_get_agent_data_buffer(mcc, size); + } else { + return main_chan->recv_buf; + } } static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc, @@ -911,6 +916,9 @@ static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc, uint32_t size, uint8_t *msg) { + if (type == SPICE_MSGC_MAIN_AGENT_DATA) { + reds_release_agent_data_buffer(msg); + } } static int main_channel_config_socket(RedChannelClient *rcc) diff --git a/server/reds.c b/server/reds.c index 17b8f7e..5d78d58 100644 --- a/server/reds.c +++ b/server/reds.c @@ -172,6 +172,8 @@ typedef struct VDIPortState { Ring external_bufs; Ring internal_bufs; Ring write_queue; + SpiceCharDeviceWriteBuffer *recv_from_client_buf; + int recv_from_client_buf_pushed; AgentMsgFilter write_filter; /* read from agent */ @@ -1179,6 +1181,37 @@ void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens) num_tokens); } +uint8_t *reds_get_agent_data_buffer(MainChannelClient *mcc, size_t size) +{ + VDIPortState *dev_state = &reds->agent_state; + RedClient *client; + + if (!dev_state->base) { + return NULL; + } + + client = main_channel_client_get_base(mcc)->client; + dev_state->recv_from_client_buf = spice_char_device_write_buffer_get(dev_state->base, + client, + size + sizeof(VDIChunkHeader)); + dev_state->recv_from_client_buf_pushed = FALSE; + return dev_state->recv_from_client_buf->buf + sizeof(VDIChunkHeader); +} + +void reds_release_agent_data_buffer(uint8_t *buf) +{ + VDIPortState *dev_state = &reds->agent_state; + + spice_assert(buf == dev_state->recv_from_client_buf->buf + sizeof(VDIChunkHeader)); + + if (!dev_state->recv_from_client_buf_pushed) { + spice_char_device_write_buffer_release(reds->agent_state.base, + dev_state->recv_from_client_buf); + dev_state->recv_from_client_buf = NULL; + dev_state->recv_from_client_buf_pushed = FALSE; + } +} + 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 diff --git a/server/reds.h b/server/reds.h index 674052a..f3d2ffa 100644 --- a/server/reds.h +++ b/server/reds.h @@ -147,6 +147,8 @@ void reds_update_stat_value(uint32_t value); void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens); void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens); +uint8_t *reds_get_agent_data_buffer(MainChannelClient *mcc, size_t size); +void reds_release_agent_data_buffer(uint8_t *buf); 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 -- 1.7.7.6 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel