[Spice-devel] [PATCH spice-server 07/14] agent: use SpiceCharDeviceWriteBuffer for agent data from the client
Hans de Goede
hdegoede at redhat.com
Mon Jul 2 06:58:35 PDT 2012
Hi,
On 06/27/2012 05:16 PM, Yonit Halperin wrote:
> 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);
> +}
This assumes that there will be max 1 agent_data_buffer in flight at all times. So I suggest adding
a "spice_assert(dev_state->recv_from_client_buf == NULL)".
> +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;
> + }
> +}
And move the dev_state->recv_from_client_buf = NULL out of the if block here.
Regards,
Hans
More information about the Spice-devel
mailing list