[Spice-devel] [PATCH spice-server 07/14] agent: use SpiceCharDeviceWriteBuffer for agent data from the client

Yonit Halperin yhalperi at redhat.com
Wed Jun 27 08:16:45 PDT 2012


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



More information about the Spice-devel mailing list