[Spice-commits] 23 commits - server/inputs_channel.c server/main_channel.c server/red_channel.c server/red_channel.h server/red_tunnel_worker.c server/red_worker.c server/smartcard.c

Alon Levy alon at kemper.freedesktop.org
Mon Feb 7 09:22:58 PST 2011


 server/inputs_channel.c    |   15 ++++--
 server/main_channel.c      |   37 ++++++++-------
 server/red_channel.c       |  106 +++++++++++++++++++++++++++++++++------------
 server/red_channel.h       |   41 +++++++++++++++--
 server/red_tunnel_worker.c |    9 ++-
 server/red_worker.c        |   14 ++---
 server/smartcard.c         |   15 ++++--
 7 files changed, 172 insertions(+), 65 deletions(-)

New commits:
commit 8c17f83940d3b8c800648117dc8ec131c56b6924
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 17:29:45 2010 +0200

    server/red_channel: style fix in red_channel_init_send_data

diff --git a/server/red_channel.c b/server/red_channel.c
index a51359a..6008876 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -458,10 +458,10 @@ void red_channel_reset_send_data(RedChannel *channel)
 
 void red_channel_init_send_data(RedChannel *channel, uint16_t msg_type, PipeItem *item)
 {
+    ASSERT(channel->send_data.item == NULL);
     channel->send_data.header->type = msg_type;
+    channel->send_data.item = item;
     if (item) {
-        ASSERT(channel->send_data.item == NULL);
-        channel->send_data.item = item;
         channel->hold_item(item);
     }
 }
commit c4d028510d9b5ec5221eabc9bf68433c80fe7b7c
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 15:08:50 2010 +0200

    server/red_channel: red_channel_pipe_clear: assert on NULL channel

diff --git a/server/red_channel.c b/server/red_channel.c
index 205eaf9..a51359a 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -603,10 +603,11 @@ int red_channel_is_connected(RedChannel *channel)
 void red_channel_pipe_clear(RedChannel *channel)
 {
     PipeItem *item;
+
+    ASSERT(channel);
     if (channel->send_data.item) {
         channel->release_item(channel, channel->send_data.item, TRUE);
     }
-
     while ((item = (PipeItem *)ring_get_head(&channel->pipe))) {
         ring_remove(&item->link);
         channel->release_item(channel, item, FALSE);
commit e9103c67addba3d3ac9cc2d2a45341a4489e0c71
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 15:06:10 2010 +0200

    server/red_channel: add TODO

diff --git a/server/red_channel.c b/server/red_channel.c
index 2a7a5ff..205eaf9 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -64,6 +64,10 @@ static int red_peer_receive(RedsStreamContext *peer, uint8_t *buf, uint32_t size
     return pos - buf;
 }
 
+// TODO: this implementation, as opposed to the old implementation in red_worker,
+// does many calls to red_peer_receive and through it cb_read, and thus avoids pointer
+// arithmetic for the case where a single cb_read could return multiple messages. But
+// this is suboptimal potentially. Profile and consider fixing.
 static void red_peer_handle_incoming(RedsStreamContext *peer, IncomingHandler *handler)
 {
     int bytes_read;
commit e655c5d26e7ce7de32586d4d2be48c101e3aa4f3
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 12:37:46 2010 +0200

    server/red_channel: export red_channel_send

diff --git a/server/red_channel.c b/server/red_channel.c
index 04fc643..2a7a5ff 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -462,7 +462,7 @@ void red_channel_init_send_data(RedChannel *channel, uint16_t msg_type, PipeItem
     }
 }
 
-static void red_channel_send(RedChannel *channel)
+void red_channel_send(RedChannel *channel)
 {
     red_peer_handle_outgoing(channel->peer, &channel->outgoing);
 }
diff --git a/server/red_channel.h b/server/red_channel.h
index 68de084..2ee6566 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -242,5 +242,6 @@ void red_channel_pipe_clear(RedChannel *channel);
 //  red_wait_pipe_item_sent
 //  handle_channel_events - this is the only one that was used before, and was in red_channel.c
 void red_channel_receive(RedChannel *channel);
+void red_channel_send(RedChannel *channel);
 
 #endif
commit 10692e20cab5f1897748c4f9249823f468d39d51
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 01:31:42 2010 +0200

    server/red_channel: add red_channel_waiting_for_ack
    
    small inline function to have the ack window logic.

diff --git a/server/red_channel.c b/server/red_channel.c
index 93338b6..04fc643 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -572,17 +572,20 @@ void red_channel_pipe_add_type(RedChannel *channel, int pipe_item_type)
     red_channel_push(channel);
 }
 
-static PipeItem *red_channel_pipe_get(RedChannel *channel)
+static inline int red_channel_waiting_for_ack(RedChannel *channel)
+{
+    return (channel->handle_acks && (channel->ack_data.messages_window > channel->ack_data.client_window * 2));
+}
+
+static inline PipeItem *red_channel_pipe_get(RedChannel *channel)
 {
     PipeItem *item;
 
     if (!channel || channel->send_data.blocked ||
-        (channel->handle_acks &&
-         (channel->ack_data.messages_window > channel->ack_data.client_window * 2)) ||
+        red_channel_waiting_for_ack(channel) ||
         !(item = (PipeItem *)ring_get_tail(&channel->pipe))) {
         return NULL;
     }
-
     --channel->pipe_size;
     ring_remove(&item->link);
     return item;
commit f45d17d68b06e6492a3981e5a117218ba71853f5
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 01:31:06 2010 +0200

    server/red_channel: protect red_channel_push from NULL

diff --git a/server/red_channel.c b/server/red_channel.c
index 62ae4a6..93338b6 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -481,6 +481,10 @@ void red_channel_push(RedChannel *channel)
 {
     PipeItem *pipe_item;
 
+    if (!channel) {
+        return;
+    }
+
     if (!channel->during_send) {
         channel->during_send = TRUE;
     } else {
commit 3476fe428d43505da828a8c6bfdd65e7f320325c
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Nov 8 10:42:14 2010 +0200

    server/red_channel: reset pipe_size on clear (from red_worker)

diff --git a/server/red_channel.c b/server/red_channel.c
index 6165d0e..62ae4a6 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -600,5 +600,6 @@ void red_channel_pipe_clear(RedChannel *channel)
         ring_remove(&item->link);
         channel->release_item(channel, item, FALSE);
     }
+    channel->pipe_size = 0;
 }
 
commit 5062433d8af45822371b6487a8d7baea23071d18
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:14:51 2010 +0200

    server/red_channel: red_channel_event: push on blocked
    
    try to push either on signal (write available) or when blocked
    and read signaled. From red_worker, copied for compatibility when
    switching later to RedChannel in red_worker. Doesn't make a lot of
    sense (but works), see comment in patch.

diff --git a/server/red_channel.c b/server/red_channel.c
index faec613..6165d0e 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -424,7 +424,12 @@ static void red_channel_event(int fd, int event, void *data)
     if (event & SPICE_WATCH_EVENT_READ) {
         red_channel_receive(channel);
     }
-    if (event & SPICE_WATCH_EVENT_WRITE) {
+    // TODO: || channel->send_data.blocked ? (from red_worker. doesn't really make sense if we have an event
+    // fired in that case)
+    if (event & SPICE_WATCH_EVENT_WRITE || channel->send_data.blocked) {
+        if (channel->send_data.blocked && ! (event & SPICE_WATCH_EVENT_WRITE)) {
+            red_printf("pushing because of blocked");
+        }
         red_channel_push(channel);
     }
 }
commit 23f13aa983f6e2e07af586374381b8f0f24d24bc
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:13:51 2010 +0200

    server/red_channel: use red_channel_receive

diff --git a/server/red_channel.c b/server/red_channel.c
index 20f62ed..faec613 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -422,7 +422,7 @@ static void red_channel_event(int fd, int event, void *data)
     RedChannel *channel = (RedChannel *)data;
 
     if (event & SPICE_WATCH_EVENT_READ) {
-        red_peer_handle_incoming(channel->peer, &channel->incoming);
+        red_channel_receive(channel);
     }
     if (event & SPICE_WATCH_EVENT_WRITE) {
         red_channel_push(channel);
commit a5afee2842ba172927cd1127d69c27236e2f1075
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:13:27 2010 +0200

    server/red_channel: add empty handle of SPICE_MSGC_DISCONNECTING
    
    Simply ignored in red_channel_handle_message

diff --git a/server/red_channel.c b/server/red_channel.c
index b582cd4..20f62ed 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -408,6 +408,8 @@ int red_channel_handle_message(RedChannel *channel, uint32_t size,
             red_channel_push(channel);
         }
         break;
+    case SPICE_MSGC_DISCONNECTING:
+        break;
     default:
         red_printf("invalid message type %u", type);
         return FALSE;
commit 74d74054934f3255e6bbacac58b7d55df6f9ae7f
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:07:35 2010 +0200

    server/red_channel: add red_channel_receive (for red_worker)

diff --git a/server/red_channel.c b/server/red_channel.c
index 6bcf654..b582cd4 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -143,6 +143,11 @@ static void red_peer_handle_incoming(RedsStreamContext *peer, IncomingHandler *h
     }
 }
 
+void red_channel_receive(RedChannel *channel)
+{
+    red_peer_handle_incoming(channel->peer, &channel->incoming);
+}
+
 static void red_peer_handle_outgoing(RedsStreamContext *peer, OutgoingHandler *handler)
 {
     int n;
diff --git a/server/red_channel.h b/server/red_channel.h
index 5a05b82..68de084 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -234,5 +234,13 @@ void red_channel_push(RedChannel *channel);
 // current red_channel_shutdown also closes the socket - is there a socket to close?
 // are we reading from an fd here? arghh
 void red_channel_pipe_clear(RedChannel *channel);
+// Again, used in various places outside of event handler context (or in other event handler
+// contexts):
+//  flush_display_commands/flush_cursor_commands
+//  display_channel_wait_for_init
+//  red_wait_outgoing_item
+//  red_wait_pipe_item_sent
+//  handle_channel_events - this is the only one that was used before, and was in red_channel.c
+void red_channel_receive(RedChannel *channel);
 
 #endif
commit c0b7abaa486f081eb67538c7e341f43f7182be75
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:06:36 2010 +0200

    server/red_channel: unstatic red_channel_pipe_clear (for red_worker)

diff --git a/server/red_channel.c b/server/red_channel.c
index 265040f..6bcf654 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -30,7 +30,6 @@
 #include "red_channel.h"
 
 static PipeItem *red_channel_pipe_get(RedChannel *channel);
-static void red_channel_pipe_clear(RedChannel *channel);
 static void red_channel_event(int fd, int event, void *data);
 
 /* return the number of bytes read. -1 in case of error */
@@ -578,7 +577,7 @@ int red_channel_is_connected(RedChannel *channel)
     return !!channel->peer;
 }
 
-static void red_channel_pipe_clear(RedChannel *channel)
+void red_channel_pipe_clear(RedChannel *channel)
 {
     PipeItem *item;
     if (channel->send_data.item) {
diff --git a/server/red_channel.h b/server/red_channel.h
index 19f1f67..5a05b82 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -230,5 +230,9 @@ void red_channel_pipe_add_type(RedChannel *channel, int pipe_item_type);
 // should be that they ""try"" a little harder, but if the event system is correct it
 // should not make any difference.
 void red_channel_push(RedChannel *channel);
+// TODO: again - what is the context exactly? this happens in channel disconnect. but our
+// current red_channel_shutdown also closes the socket - is there a socket to close?
+// are we reading from an fd here? arghh
+void red_channel_pipe_clear(RedChannel *channel);
 
 #endif
commit a30a602654d7760da62cf4b7cefd4a5b5bfe2081
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 13:01:48 2010 +0200

    server/red_channel: unstatic red_channel_push (for red_worker)

diff --git a/server/red_channel.c b/server/red_channel.c
index b5ee32d..265040f 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -29,7 +29,6 @@
 #include "stat.h"
 #include "red_channel.h"
 
-static void red_channel_push(RedChannel *channel);
 static PipeItem *red_channel_pipe_get(RedChannel *channel);
 static void red_channel_pipe_clear(RedChannel *channel);
 static void red_channel_event(int fd, int event, void *data);
@@ -467,7 +466,7 @@ void red_channel_begin_send_message(RedChannel *channel)
     red_channel_send(channel);
 }
 
-static void red_channel_push(RedChannel *channel)
+void red_channel_push(RedChannel *channel)
 {
     PipeItem *pipe_item;
 
diff --git a/server/red_channel.h b/server/red_channel.h
index 5135970..19f1f67 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -225,4 +225,10 @@ void red_channel_pipe_add_tail(RedChannel *channel, PipeItem *item);
 /* for types that use this routine -> the pipe item should be freed */
 void red_channel_pipe_add_type(RedChannel *channel, int pipe_item_type);
 
+// TODO: unstaticed for display/cursor channels. they do some specific pushes not through
+// adding elements or on events. but not sure if this is actually required (only result
+// should be that they ""try"" a little harder, but if the event system is correct it
+// should not make any difference.
+void red_channel_push(RedChannel *channel);
+
 #endif
commit 57b719b9914d65b43f7fcd6c39c64ec626016f47
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:43:46 2010 +0200

    server/red_channel: two 80 column fixes

diff --git a/server/red_channel.c b/server/red_channel.c
index 717da02..b5ee32d 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -115,8 +115,9 @@ static void red_peer_handle_incoming(RedsStreamContext *peer, IncomingHandler *h
         }
 
         if (handler->parser) {
-            parsed = handler->parser(handler->msg, handler->msg + handler->header.size, handler->header.type,
-                                     SPICE_VERSION_MINOR, &parsed_size, &parsed_free);
+            parsed = handler->parser(handler->msg,
+                handler->msg + handler->header.size, handler->header.type,
+                SPICE_VERSION_MINOR, &parsed_size, &parsed_free);
             if (parsed == NULL) {
                 red_printf("failed to parse message type %d", handler->header.type);
                 handler->on_error(handler->opaque);
@@ -341,8 +342,9 @@ RedChannel *red_channel_create_parser(int size, RedsStreamContext *peer,
                                channel_on_outgoing_error_proc outgoing_error)
 {
     RedChannel *channel = red_channel_create(size, peer,
-        core, migrate, handle_acks, config_socket, do_nothing_disconnect, do_nothing_handle_message,
-        alloc_recv_buf, release_recv_buf, hold_item, send_item, release_item);
+        core, migrate, handle_acks, config_socket, do_nothing_disconnect,
+        do_nothing_handle_message, alloc_recv_buf, release_recv_buf, hold_item,
+        send_item, release_item);
 
     if (channel == NULL) {
         return NULL;
commit 33bede823aa2366d105a7ad9ad6949f8d4266fa9
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:42:38 2010 +0200

    server/red_channel: add public red_channel_default_peer_on_error
    
    for later use in red_worker

diff --git a/server/red_channel.c b/server/red_channel.c
index ebb181c..717da02 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -185,10 +185,8 @@ static void red_peer_handle_outgoing(RedsStreamContext *peer, OutgoingHandler *h
     }
 }
 
-static void red_channel_peer_on_error(void *opaque)
+void red_channel_default_peer_on_error(RedChannel *channel)
 {
-    RedChannel *channel = (RedChannel *)opaque;
-
     channel->disconnect(channel);
 }
 
@@ -286,7 +284,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
     channel->incoming.alloc_msg_buf = (alloc_msg_recv_buf_proc)alloc_recv_buf;
     channel->incoming.release_msg_buf = (release_msg_recv_buf_proc)release_recv_buf;
     channel->incoming.handle_message = (handle_message_proc)handle_message;
-    channel->incoming.on_error = red_channel_peer_on_error;
+    channel->incoming.on_error = (on_incoming_error_proc)red_channel_default_peer_on_error;
 
     channel->outgoing.opaque = channel;
     channel->outgoing.pos = 0;
@@ -296,7 +294,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
     channel->outgoing.get_msg_size = red_channel_peer_get_out_msg_size;
     channel->outgoing.prepare = red_channel_peer_prepare_out_msg;
     channel->outgoing.on_block = red_channel_peer_on_out_block;
-    channel->outgoing.on_error = red_channel_peer_on_error;
+    channel->outgoing.on_error = (on_outgoing_error_proc)red_channel_default_peer_on_error;
     channel->outgoing.on_msg_done = red_channel_peer_on_out_msg_done;
 
     channel->shut = 0; // came here from inputs, perhaps can be removed? XXX
diff --git a/server/red_channel.h b/server/red_channel.h
index 7c973fd..5135970 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -200,6 +200,8 @@ void red_channel_init_outgoing_messages_window(RedChannel *channel);
 int red_channel_handle_message(RedChannel *channel, uint32_t size,
                                uint16_t type, void *message);
 
+/* default error handler that disconnects channel */
+void red_channel_default_peer_on_error(RedChannel *channel);
 
 /* when preparing send_data: should call reset, then init and then add_buf per buffer that is
    being sent */
commit c322873cf0ada6af2c76a83dd7a046dc648ab8b9
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:38:31 2010 +0200

    server/red_channel: add red_channel_pipe_add_after (from red_worker)

diff --git a/server/red_channel.c b/server/red_channel.c
index b367f0f..ebb181c 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -520,6 +520,16 @@ void red_channel_pipe_add_push(RedChannel *channel, PipeItem *item)
     red_channel_push(channel);
 }
 
+void red_channel_pipe_add_after(RedChannel *channel, PipeItem *item, PipeItem *pos)
+{
+    ASSERT(channel);
+    ASSERT(pos);
+    ASSERT(item);
+
+    channel->pipe_size++;
+    ring_add_after(&item->link, &pos->link);
+}
+
 int red_channel_pipe_item_is_linked(RedChannel *channel, PipeItem *item)
 {
     return ring_item_is_linked(&item->link);
diff --git a/server/red_channel.h b/server/red_channel.h
index 0a113fc..7c973fd 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -216,6 +216,7 @@ void red_channel_begin_send_message(RedChannel *channel);
 void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type);
 void red_channel_pipe_add_push(RedChannel *channel, PipeItem *item);
 void red_channel_pipe_add(RedChannel *channel, PipeItem *item);
+void red_channel_pipe_add_after(RedChannel *channel, PipeItem *item, PipeItem *pos);
 int red_channel_pipe_item_is_linked(RedChannel *channel, PipeItem *item);
 void red_channel_pipe_item_remove(RedChannel *channel, PipeItem *item);
 void red_channel_pipe_add_tail(RedChannel *channel, PipeItem *item);
commit 23f37df54843d8b2e7e869994e160e905330d0bf
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:33:28 2010 +0200

    server/red_channel: make client ack window configurable
    
    from red_worker

diff --git a/server/red_channel.c b/server/red_channel.c
index 6f3ed73..b367f0f 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -276,6 +276,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
     channel->ack_data.messages_window = ~0;  // blocks send message (maybe use send_data.blocked +
                                              // block flags)
     channel->ack_data.client_generation = ~0;
+    channel->ack_data.client_window = CLIENT_ACK_WINDOW;
 
     channel->migrate = migrate;
     ring_init(&channel->pipe);
@@ -400,7 +401,7 @@ int red_channel_handle_message(RedChannel *channel, uint32_t size,
         break;
     case SPICE_MSGC_ACK:
         if (channel->ack_data.client_generation == channel->ack_data.generation) {
-            channel->ack_data.messages_window -= CLIENT_ACK_WINDOW;
+            channel->ack_data.messages_window -= channel->ack_data.client_window;
             red_channel_push(channel);
         }
         break;
@@ -552,7 +553,8 @@ static PipeItem *red_channel_pipe_get(RedChannel *channel)
     PipeItem *item;
 
     if (!channel || channel->send_data.blocked ||
-        (channel->handle_acks && (channel->ack_data.messages_window > CLIENT_ACK_WINDOW * 2)) ||
+        (channel->handle_acks &&
+         (channel->ack_data.messages_window > channel->ack_data.client_window * 2)) ||
         !(item = (PipeItem *)ring_get_tail(&channel->pipe))) {
         return NULL;
     }
diff --git a/server/red_channel.h b/server/red_channel.h
index c97509c..0a113fc 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -123,6 +123,7 @@ struct RedChannel {
         uint32_t generation;
         uint32_t client_generation;
         uint32_t messages_window;
+        uint32_t client_window;
     } ack_data;
 
     Ring pipe;
commit 0512726b680a3cfcbe0081d188ec1a4c39cd2434
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:30:47 2010 +0200

    server/red_channel (tunnel): change sig of red_channel_handle_message
    
    for later usage with red_worker

diff --git a/server/red_channel.c b/server/red_channel.c
index be66dfb..6f3ed73 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -387,15 +387,16 @@ void red_channel_init_outgoing_messages_window(RedChannel *channel)
     red_channel_push(channel);
 }
 
-int red_channel_handle_message(RedChannel *channel, SpiceDataHeader *header, uint8_t *msg)
+int red_channel_handle_message(RedChannel *channel, uint32_t size,
+                               uint16_t type, void *message)
 {
-    switch (header->type) {
+    switch (type) {
     case SPICE_MSGC_ACK_SYNC:
-        if (header->size != sizeof(uint32_t)) {
+        if (size != sizeof(uint32_t)) {
             red_printf("bad message size");
             return FALSE;
         }
-        channel->ack_data.client_generation = *(uint32_t *)(msg);
+        channel->ack_data.client_generation = *(uint32_t *)(message);
         break;
     case SPICE_MSGC_ACK:
         if (channel->ack_data.client_generation == channel->ack_data.generation) {
@@ -404,7 +405,7 @@ int red_channel_handle_message(RedChannel *channel, SpiceDataHeader *header, uin
         }
         break;
     default:
-        red_printf("invalid message type %u", header->type);
+        red_printf("invalid message type %u", type);
         return FALSE;
     }
     return TRUE;
diff --git a/server/red_channel.h b/server/red_channel.h
index f3c25d4..c97509c 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -196,7 +196,9 @@ void red_channel_shutdown(RedChannel *channel);
 void red_channel_init_outgoing_messages_window(RedChannel *channel);
 
 /* handles general channel msgs from the client */
-int red_channel_handle_message(RedChannel *channel, SpiceDataHeader *header, uint8_t *msg);
+int red_channel_handle_message(RedChannel *channel, uint32_t size,
+                               uint16_t type, void *message);
+
 
 /* when preparing send_data: should call reset, then init and then add_buf per buffer that is
    being sent */
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 2553943..f60894b 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -2247,7 +2247,7 @@ static int tunnel_channel_handle_message(RedChannel *channel, SpiceDataHeader *h
         }
         break;
     default:
-        return red_channel_handle_message(channel, header, msg);
+        return red_channel_handle_message(channel, header->size, header->type, msg);
     }
 
     switch (header->type) {
@@ -2325,7 +2325,7 @@ static int tunnel_channel_handle_message(RedChannel *channel, SpiceDataHeader *h
         }
         return tunnel_channel_handle_migrate_data(tunnel_channel, (TunnelMigrateData *)msg);
     default:
-        return red_channel_handle_message(channel, header, msg);
+        return red_channel_handle_message(channel, header->size, header->type, msg);
     }
     return TRUE;
 }
commit 26dda37c27b87b63d2603b0e9279334ce870b142
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:20:47 2010 +0200

    server/red_channel: make MAX_SEND_VEC 100
    
    MAX_SEND_VEC was 100 for DisplayChannel's RedChannel implementation which is being replaced
    with RedChannel in red_channel. So changing from 50 to 100 in red_channel
    (make this configurble?) - effectively increased memory usage by:
    (100-50)*sizeof(iovec)*(num_of_channels-2) ==(arch 64bit) 50*16*6 ~ 5k
    Not terrible.

diff --git a/server/red_channel.h b/server/red_channel.h
index b298127..f3c25d4 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -29,7 +29,7 @@
 #include "server/demarshallers.h"
 
 #define MAX_SEND_BUFS 1000
-#define MAX_SEND_VEC 50
+#define MAX_SEND_VEC 100
 #define CLIENT_ACK_WINDOW 20
 
 /* Basic interface for channels, without using the RedChannel interface.
commit b4c3b8a58625503c4d9e2dc32e79909bc1144984
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Nov 7 12:19:18 2010 +0200

    server/red_channel: reflect SpiceDataHeader fields in handle_parsed_proc

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index 9372c6f..c930d4d 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -290,7 +290,7 @@ static void inputs_channel_send_item(RedChannel *channel, PipeItem *base)
     red_channel_begin_send_message(channel);
 }
 
-static int inputs_channel_handle_parsed(RedChannel *channel, size_t size, uint32_t type, void *message)
+static int inputs_channel_handle_parsed(RedChannel *channel, uint32_t size, uint16_t type, void *message)
 {
     InputsChannel *inputs_channel = (InputsChannel *)channel;
     uint8_t *buf = (uint8_t *)message;
diff --git a/server/main_channel.c b/server/main_channel.c
index 626189b..67ac72f 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -655,7 +655,7 @@ static void main_channel_release_pipe_item(RedChannel *channel,
     free(base);
 }
 
-static int main_channel_handle_parsed(RedChannel *channel, size_t size, uint32_t type, void *message)
+static int main_channel_handle_parsed(RedChannel *channel, uint32_t size, uint16_t type, void *message)
 {
     MainChannel *main_chan = SPICE_CONTAINEROF(channel, MainChannel, base);
 
diff --git a/server/red_channel.h b/server/red_channel.h
index 1521f41..b298127 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -38,7 +38,7 @@
 
 typedef int (*handle_message_proc)(void *opaque,
                                    SpiceDataHeader *header, uint8_t *msg);
-typedef int (*handle_parsed_proc)(void *opaque, size_t size, uint32_t type, void *message);
+typedef int (*handle_parsed_proc)(void *opaque, uint32_t size, uint16_t type, void *message);
 typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, SpiceDataHeader *msg_header);
 typedef void (*release_msg_recv_buf_proc)(void *opaque,
                                           SpiceDataHeader *msg_header, uint8_t *msg);
@@ -98,7 +98,7 @@ typedef struct RedChannel RedChannel;
 
 typedef uint8_t *(*channel_alloc_msg_recv_buf_proc)(RedChannel *channel,
                                                     SpiceDataHeader *msg_header);
-typedef int (*channel_handle_parsed_proc)(RedChannel *channel, size_t size, uint32_t type,
+typedef int (*channel_handle_parsed_proc)(RedChannel *channel, uint32_t size, uint16_t type,
                                         void *message);
 typedef int (*channel_handle_message_proc)(RedChannel *channel,
                                            SpiceDataHeader *header, uint8_t *msg);
commit 194a6be5f78cb04a1891d2f74efbab828dab3d39
Author: Alon Levy <alevy at redhat.com>
Date:   Thu Nov 4 17:21:46 2010 +0200

    server/red_channel: add red_channel_pipe_add_push

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index 9b6c791..9372c6f 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -243,7 +243,7 @@ static void inputs_pipe_add_type(InputsChannel *channel, int type)
 {
     InputsPipeItem* pipe_item = inputs_pipe_item_new(channel, type);
 
-    red_channel_pipe_add(&channel->base, &pipe_item->base);
+    red_channel_pipe_add_push(&channel->base, &pipe_item->base);
 }
 
 static void inputs_channel_release_pipe_item(RedChannel *channel,
@@ -476,7 +476,7 @@ static void inputs_migrate(Channel *channel)
 
     ASSERT(g_inputs_channel == (InputsChannel *)channel->data);
     item = inputs_pipe_item_new(inputs_channel, PIPE_ITEM_MIGRATE);
-    red_channel_pipe_add(&inputs_channel->base, &item->base);
+    red_channel_pipe_add_push(&inputs_channel->base, &item->base);
 }
 
 static void inputs_pipe_add_init(InputsChannel *inputs_channel)
@@ -486,7 +486,7 @@ static void inputs_pipe_add_init(InputsChannel *inputs_channel)
     red_channel_pipe_item_init(&inputs_channel->base, &item->base,
                                PIPE_ITEM_INIT);
     item->modifiers = kbd_get_leds(keyboard);
-    red_channel_pipe_add(&inputs_channel->base, &item->base);
+    red_channel_pipe_add_push(&inputs_channel->base, &item->base);
 }
 
 static int inputs_channel_config_socket(RedChannel *channel)
@@ -545,7 +545,7 @@ static void inputs_push_keyboard_modifiers(uint8_t modifiers)
         return;
     }
     item = inputs_key_modifiers_item_new(g_inputs_channel, modifiers);
-    red_channel_pipe_add(&g_inputs_channel->base, &item->base);
+    red_channel_pipe_add_push(&g_inputs_channel->base, &item->base);
 }
 
 void inputs_on_keyboard_leds_change(void *opaque, uint8_t leds)
diff --git a/server/main_channel.c b/server/main_channel.c
index 1abf107..626189b 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -277,7 +277,7 @@ static void main_channel_push_channels(MainChannel *main_chan)
     RedsOutItem *item;
 
     item = main_pipe_item_new(main_chan, SPICE_MSG_MAIN_CHANNELS_LIST);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_channels(MainChannel *main_chan)
@@ -301,7 +301,7 @@ int main_channel_push_ping(Channel *channel, int size)
         return FALSE;
     }
     item = main_ping_item_new(main_chan, size);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
     return TRUE;
 }
 
@@ -331,7 +331,7 @@ void main_channel_push_mouse_mode(Channel *channel, int current_mode,
 
     item = main_mouse_mode_item_new(main_chan, current_mode,
                                     is_client_mouse_allowed);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_mouse_mode(MainChannel *main_chan, int current_mode, int is_client_mouse_allowed)
@@ -352,7 +352,7 @@ void main_channel_push_agent_connected(Channel *channel)
     MainChannel *main_chan = channel->data;
 
     item = main_pipe_item_new(main_chan, SPICE_MSG_MAIN_AGENT_CONNECTED);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 void main_channel_push_agent_disconnected(Channel *channel)
@@ -361,7 +361,7 @@ void main_channel_push_agent_disconnected(Channel *channel)
     MainChannel *main_chan = channel->data;
 
     item = main_pipe_item_new(main_chan, SPICE_MSG_MAIN_AGENT_DISCONNECTED);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_agent_disconnected(MainChannel *main_chan)
@@ -378,7 +378,7 @@ void main_channel_push_tokens(Channel *channel, uint32_t num_tokens)
     MainChannel *main_chan = channel->data;
     TokensPipeItem *item = main_tokens_item_new(main_chan, num_tokens);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_tokens(MainChannel *main_chan, uint32_t num_tokens)
@@ -397,7 +397,7 @@ void main_channel_push_agent_data(Channel *channel, uint8_t* data, size_t len,
     AgentDataPipeItem *item;
 
     item = main_agent_data_item_new(main_chan, data, len, free_data, opaque);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_agent_data(MainChannel *main_chan,
@@ -411,7 +411,7 @@ static void main_channel_push_migrate_data_item(MainChannel *main_chan)
 {
     RedsOutItem *item = main_pipe_item_new(main_chan, SPICE_MSG_MIGRATE_DATA);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_migrate_data_item(MainChannel *main_chan)
@@ -442,7 +442,7 @@ void main_channel_push_init(Channel *channel, int connection_id,
     item = main_init_item_new(main_chan,
              connection_id, display_channels_hint, current_mouse_mode,
              is_client_mouse_allowed, multi_media_time, ram_hint);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_init(MainChannel *main_chan,
@@ -469,7 +469,7 @@ void main_channel_push_notify(Channel *channel, uint8_t *mess, const int mess_le
     MainChannel *main_chan = channel->data;
     NotifyPipeItem *item = main_notify_item_new(main_chan, mess, mess_len);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_notify(MainChannel *main_chan, NotifyPipeItem *item)
@@ -494,7 +494,7 @@ void main_channel_push_migrate_begin(Channel *channel, int port, int sport,
     MigrateBeginPipeItem *item = main_migrate_begin_item_new(main_chan, port,
         sport, host, cert_pub_key_type, cert_pub_key_len, cert_pub_key);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_migrate_begin(MainChannel *main_chan,
@@ -518,7 +518,7 @@ void main_channel_push_migrate(Channel *channel)
     MainChannel *main_chan = channel->data;
     RedsOutItem *item = main_pipe_item_new(main_chan, SPICE_MSG_MIGRATE);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static void main_channel_marshall_migrate(MainChannel *main_chan)
@@ -535,7 +535,7 @@ void main_channel_push_migrate_cancel(Channel *channel)
     RedsOutItem *item = main_pipe_item_new(main_chan,
                                            SPICE_MSG_MAIN_MIGRATE_CANCEL);
 
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 void main_channel_push_multi_media_time(Channel *channel, int time)
@@ -544,7 +544,7 @@ void main_channel_push_multi_media_time(Channel *channel, int time)
 
     MultiMediaTimePipeItem *item =
         main_multi_media_time_item_new(main_chan, time);
-    red_channel_pipe_add(&main_chan->base, &item->base);
+    red_channel_pipe_add_push(&main_chan->base, &item->base);
 }
 
 static PipeItem *main_migrate_switch_item_new(MainChannel *main_chan)
@@ -560,7 +560,7 @@ void main_channel_push_migrate_switch(Channel *channel)
 {
     MainChannel *main_chan = channel->data;
 
-    red_channel_pipe_add(&main_chan->base,
+    red_channel_pipe_add_push(&main_chan->base,
         main_migrate_switch_item_new(main_chan));
 }
 
diff --git a/server/red_channel.c b/server/red_channel.c
index afa3ff2..be66dfb 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -507,7 +507,14 @@ void red_channel_pipe_add(RedChannel *channel, PipeItem *item)
 
     channel->pipe_size++;
     ring_add(&channel->pipe, &item->link);
+}
+
+void red_channel_pipe_add_push(RedChannel *channel, PipeItem *item)
+{
+    ASSERT(channel);
 
+    channel->pipe_size++;
+    ring_add(&channel->pipe, &item->link);
     red_channel_push(channel);
 }
 
diff --git a/server/red_channel.h b/server/red_channel.h
index a778ffb..1521f41 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -211,6 +211,7 @@ void red_channel_set_message_serial(RedChannel *channel, uint64_t);
 void red_channel_begin_send_message(RedChannel *channel);
 
 void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type);
+void red_channel_pipe_add_push(RedChannel *channel, PipeItem *item);
 void red_channel_pipe_add(RedChannel *channel, PipeItem *item);
 int red_channel_pipe_item_is_linked(RedChannel *channel, PipeItem *item);
 void red_channel_pipe_item_remove(RedChannel *channel, PipeItem *item);
diff --git a/server/smartcard.c b/server/smartcard.c
index 93142cc..b22d7c4 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -353,9 +353,9 @@ static void smartcard_channel_disconnect(RedChannel *channel)
 /* this is called from both device input and client input. since the device is
  * a usb device, the context is still the main thread (kvm_main_loop, timers)
  * so no mutex is required. */
-static void smartcard_channel_pipe_add(SmartCardChannel *channel, PipeItem *item)
+static void smartcard_channel_pipe_add_push(SmartCardChannel *channel, PipeItem *item)
 {
-    red_channel_pipe_add(&channel->base, item);
+    red_channel_pipe_add_push(&channel->base, item);
 }
 
 static void smartcard_push_error(SmartCardChannel* channel, reader_id_t reader_id, VSCErrorCode error)
@@ -365,7 +365,7 @@ static void smartcard_push_error(SmartCardChannel* channel, reader_id_t reader_i
     error_item->base.type = PIPE_ITEM_TYPE_ERROR;
     error_item->reader_id = reader_id;
     error_item->error = error;
-    smartcard_channel_pipe_add(channel, &error_item->base);
+    smartcard_channel_pipe_add_push(channel, &error_item->base);
 }
 
 static void smartcard_push_reader_add_response(SmartCardChannel *channel, uint32_t reader_id)
@@ -374,7 +374,7 @@ static void smartcard_push_reader_add_response(SmartCardChannel *channel, uint32
 
     rar_item->base.type = PIPE_ITEM_TYPE_READER_ADD_RESPONSE;
     rar_item->reader_id = reader_id;
-    smartcard_channel_pipe_add(channel, &rar_item->base);
+    smartcard_channel_pipe_add_push(channel, &rar_item->base);
 }
 
 static void smartcard_push_vscmsg(SmartCardChannel *channel, VSCMsgHeader *vheader)
@@ -383,7 +383,7 @@ static void smartcard_push_vscmsg(SmartCardChannel *channel, VSCMsgHeader *vhead
 
     msg_item->base.type = PIPE_ITEM_TYPE_MSG;
     msg_item->vheader = vheader;
-    smartcard_channel_pipe_add(channel, &msg_item->base);
+    smartcard_channel_pipe_add_push(channel, &msg_item->base);
 }
 
 void smartcard_on_message_from_device(SmartCardChannel *smartcard_channel,
commit 7dfd7a0c779da2df2c90ea59a9defb313779aaca
Author: Alon Levy <alevy at redhat.com>
Date:   Thu Nov 4 17:20:24 2010 +0200

    server/red_channel: add hold_item (from red_worker)
    
    hold_item called on init_send_data, matching release.
    This is not the behavior of red_worker - we ref++ (==hold_item) when
    sending the item, and --refs when releasing it, instead of only holding
    if the send is blocked.
    
    Note 1: Naming: hold_pipe_item is the proc name, the variable is called
    hold_item, this is similar to release_item/release_pipe_item naming.
    
    Note 2: All channels have empty implementation, we later use this when
    red_worker get's RedChannelized.

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index b7ae55a..9b6c791 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -508,6 +508,10 @@ static int inputs_channel_config_socket(RedChannel *channel)
     return TRUE;
 }
 
+static void inputs_channel_hold_pipe_item(PipeItem *item)
+{
+}
+
 static void inputs_link(Channel *channel, RedsStreamContext *peer, int migration,
                         int num_common_caps, uint32_t *common_caps, int num_caps,
                         uint32_t *caps)
@@ -523,6 +527,7 @@ static void inputs_link(Channel *channel, RedsStreamContext *peer, int migration
         ,inputs_channel_handle_parsed
         ,inputs_channel_alloc_msg_rcv_buf
         ,inputs_channel_release_msg_rcv_buf
+        ,inputs_channel_hold_pipe_item
         ,inputs_channel_send_item
         ,inputs_channel_release_pipe_item
         ,inputs_channel_on_incoming_error
diff --git a/server/main_channel.c b/server/main_channel.c
index f1fb4c6..1abf107 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -776,6 +776,10 @@ static int main_channel_config_socket(RedChannel *channel)
     return TRUE;
 }
 
+static void main_channel_hold_pipe_item(PipeItem *item)
+{
+}
+
 static void main_channel_link(Channel *channel, RedsStreamContext *peer, int migration,
                         int num_common_caps, uint32_t *common_caps, int num_caps,
                         uint32_t *caps)
@@ -791,6 +795,7 @@ static void main_channel_link(Channel *channel, RedsStreamContext *peer, int mig
         ,main_channel_handle_parsed
         ,main_channel_alloc_msg_rcv_buf
         ,main_channel_release_msg_rcv_buf
+        ,main_channel_hold_pipe_item
         ,main_channel_send_item
         ,main_channel_release_pipe_item
         ,main_channel_on_error
diff --git a/server/red_channel.c b/server/red_channel.c
index 584b92e..afa3ff2 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -224,6 +224,7 @@ static void red_channel_peer_prepare_out_msg(void *opaque, struct iovec *vec, in
 static void red_channel_peer_on_out_block(void *opaque)
 {
     RedChannel *channel = (RedChannel *)opaque;
+
     channel->send_data.blocked = TRUE;
     channel->core->watch_update_mask(channel->peer->watch,
                                      SPICE_WATCH_EVENT_READ |
@@ -253,6 +254,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
                                channel_handle_message_proc handle_message,
                                channel_alloc_msg_recv_buf_proc alloc_recv_buf,
                                channel_release_msg_recv_buf_proc release_recv_buf,
+                               channel_hold_pipe_item_proc hold_item,
                                channel_send_pipe_item_proc send_item,
                                channel_release_pipe_item_proc release_item)
 {
@@ -267,6 +269,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
     channel->disconnect = disconnect;
     channel->send_item = send_item;
     channel->release_item = release_item;
+    channel->hold_item = hold_item;
 
     channel->peer = peer;
     channel->core = core;
@@ -332,6 +335,7 @@ RedChannel *red_channel_create_parser(int size, RedsStreamContext *peer,
                                channel_handle_parsed_proc handle_parsed,
                                channel_alloc_msg_recv_buf_proc alloc_recv_buf,
                                channel_release_msg_recv_buf_proc release_recv_buf,
+                               channel_hold_pipe_item_proc hold_item,
                                channel_send_pipe_item_proc send_item,
                                channel_release_pipe_item_proc release_item,
                                channel_on_incoming_error_proc incoming_error,
@@ -339,7 +343,7 @@ RedChannel *red_channel_create_parser(int size, RedsStreamContext *peer,
 {
     RedChannel *channel = red_channel_create(size, peer,
         core, migrate, handle_acks, config_socket, do_nothing_disconnect, do_nothing_handle_message,
-        alloc_recv_buf, release_recv_buf, send_item, release_item);
+        alloc_recv_buf, release_recv_buf, hold_item, send_item, release_item);
 
     if (channel == NULL) {
         return NULL;
@@ -439,7 +443,11 @@ void red_channel_reset_send_data(RedChannel *channel)
 void red_channel_init_send_data(RedChannel *channel, uint16_t msg_type, PipeItem *item)
 {
     channel->send_data.header->type = msg_type;
-    channel->send_data.item = item;
+    if (item) {
+        ASSERT(channel->send_data.item == NULL);
+        channel->send_data.item = item;
+        channel->hold_item(item);
+    }
 }
 
 static void red_channel_send(RedChannel *channel)
diff --git a/server/red_channel.h b/server/red_channel.h
index e8ebb05..a778ffb 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -107,6 +107,7 @@ typedef void (*channel_release_msg_recv_buf_proc)(RedChannel *channel,
 typedef void (*channel_disconnect_proc)(RedChannel *channel);
 typedef int (*channel_configure_socket_proc)(RedChannel *channel);
 typedef void (*channel_send_pipe_item_proc)(RedChannel *channel, PipeItem *item);
+typedef void (*channel_hold_pipe_item_proc)(PipeItem *item);
 typedef void (*channel_release_pipe_item_proc)(RedChannel *channel,
                                                PipeItem *item, int item_pushed);
 typedef void (*channel_on_incoming_error_proc)(RedChannel *channel);
@@ -145,6 +146,7 @@ struct RedChannel {
 
     channel_disconnect_proc disconnect;
     channel_send_pipe_item_proc send_item;
+    channel_hold_pipe_item_proc hold_item;
     channel_release_pipe_item_proc release_item;
 
     int during_send;
@@ -165,6 +167,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
                                channel_handle_message_proc handle_message,
                                channel_alloc_msg_recv_buf_proc alloc_recv_buf,
                                channel_release_msg_recv_buf_proc release_recv_buf,
+                               channel_hold_pipe_item_proc hold_item,
                                channel_send_pipe_item_proc send_item,
                                channel_release_pipe_item_proc release_item);
 
@@ -178,6 +181,7 @@ RedChannel *red_channel_create_parser(int size, RedsStreamContext *peer,
                                channel_handle_parsed_proc handle_parsed,
                                channel_alloc_msg_recv_buf_proc alloc_recv_buf,
                                channel_release_msg_recv_buf_proc release_recv_buf,
+                               channel_hold_pipe_item_proc hold_item,
                                channel_send_pipe_item_proc send_item,
                                channel_release_pipe_item_proc release_item,
                                channel_on_incoming_error_proc incoming_error,
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 6092a76..2553943 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -3420,6 +3420,10 @@ static void on_new_tunnel_channel(TunnelChannel *channel)
     }
 }
 
+static void tunnel_channel_hold_pipe_item(PipeItem *item)
+{
+}
+
 static void handle_tunnel_channel_link(Channel *channel, RedsStreamContext *peer, int migration,
                                        int num_common_caps, uint32_t *common_caps, int num_caps,
                                        uint32_t *caps)
@@ -3438,6 +3442,7 @@ static void handle_tunnel_channel_link(Channel *channel, RedsStreamContext *peer
                                             tunnel_channel_handle_message,
                                             tunnel_channel_alloc_msg_rcv_buf,
                                             tunnel_channel_release_msg_rcv_buf,
+                                            tunnel_channel_hold_pipe_item,
                                             tunnel_channel_send_item,
                                             tunnel_channel_release_pipe_item);
 
diff --git a/server/red_worker.c b/server/red_worker.c
index f163a71..2acef40 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -347,7 +347,7 @@ typedef struct LocalCursor {
 
 typedef struct RedChannel RedChannel;
 typedef void (*disconnect_channel_proc)(RedChannel *channel);
-typedef void (*hold_item_proc)(void *item);
+typedef void (*hold_pipe_item_proc)(void *item);
 typedef void (*release_item_proc)(RedChannel *channel, void *item);
 typedef int (*handle_message_proc)(RedChannel *channel, size_t size, uint32_t type, void *message);
 
@@ -385,7 +385,7 @@ struct RedChannel {
     } recive_data;
 
     disconnect_channel_proc disconnect;
-    hold_item_proc hold_item;
+    hold_pipe_item_proc hold_item;
     release_item_proc release_item;
     handle_message_proc handle_message;
 #ifdef RED_STATISTICS
@@ -9310,7 +9310,7 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_i
                                  RedsStreamContext *peer, int migrate,
                                  event_listener_action_proc handler,
                                  disconnect_channel_proc disconnect,
-                                 hold_item_proc hold_item,
+                                 hold_pipe_item_proc hold_item,
                                  release_item_proc release_item,
                                  handle_message_proc handle_message)
 {
@@ -9389,7 +9389,7 @@ static void handle_channel_events(EventListener *in_listener, uint32_t events)
     }
 }
 
-static void display_channel_hold_item(void *item)
+static void display_channel_hold_pipe_item(void *item)
 {
     ASSERT(item);
     switch (((PipeItem *)item)->type) {
@@ -9444,7 +9444,7 @@ static void handle_new_display_channel(RedWorker *worker, RedsStreamContext *pee
                                                             SPICE_CHANNEL_DISPLAY, peer,
                                                             migrate, handle_channel_events,
                                                             red_disconnect_display,
-                                                            display_channel_hold_item,
+                                                            display_channel_hold_pipe_item,
                                                             display_channel_release_item,
                                                             display_channel_handle_message))) {
         return;
@@ -9544,7 +9544,7 @@ static void on_new_cursor_channel(RedWorker *worker)
     }
 }
 
-static void cursor_channel_hold_item(void *item)
+static void cursor_channel_hold_pipe_item(void *item)
 {
     ASSERT(item);
     ((CursorItem *)item)->refs++;
@@ -9566,7 +9566,7 @@ static void red_connect_cursor(RedWorker *worker, RedsStreamContext *peer, int m
                                                    SPICE_CHANNEL_CURSOR, peer, migrate,
                                                    handle_channel_events,
                                                    red_disconnect_cursor,
-                                                   cursor_channel_hold_item,
+                                                   cursor_channel_hold_pipe_item,
                                                    cursor_channel_release_item,
                                                    channel_handle_message))) {
         return;
diff --git a/server/smartcard.c b/server/smartcard.c
index 7c0a5aa..93142cc 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -485,6 +485,10 @@ static int smartcard_channel_handle_message(RedChannel *channel, SpiceDataHeader
     return TRUE;
 }
 
+static void smartcard_channel_hold_pipe_item(PipeItem *item)
+{
+}
+
 static void smartcard_link(Channel *channel, RedsStreamContext *peer,
                         int migration, int num_common_caps,
                         uint32_t *common_caps, int num_caps,
@@ -502,6 +506,7 @@ static void smartcard_link(Channel *channel, RedsStreamContext *peer,
                                         smartcard_channel_handle_message,
                                         smartcard_channel_alloc_msg_rcv_buf,
                                         smartcard_channel_release_msg_rcv_buf,
+                                        smartcard_channel_hold_pipe_item,
                                         smartcard_channel_send_item,
                                         smartcard_channel_release_pipe_item);
     if (!g_smartcard_channel) {
commit e571b5ebbb5f60d264f2d2eab8ec34d389fd3752
Author: Alon Levy <alevy at redhat.com>
Date:   Thu Nov 4 17:16:01 2010 +0200

    server/red_channel: add out_bytes_counter (unused)

diff --git a/server/red_channel.c b/server/red_channel.c
index a13ef0e..584b92e 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -26,6 +26,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include "stat.h"
 #include "red_channel.h"
 
 static void red_channel_push(RedChannel *channel);
@@ -172,6 +173,7 @@ static void red_peer_handle_outgoing(RedsStreamContext *peer, OutgoingHandler *h
             }
         } else {
             handler->pos += n;
+            stat_inc_counter(handler->out_bytes_counter, n);
             if (handler->pos == handler->size) { // finished writing data
                 handler->on_msg_done(handler->opaque);
                 handler->vec = handler->vec_buf;
@@ -285,6 +287,7 @@ RedChannel *red_channel_create(int size, RedsStreamContext *peer,
     channel->outgoing.opaque = channel;
     channel->outgoing.pos = 0;
     channel->outgoing.size = 0;
+    channel->outgoing.out_bytes_counter = NULL;
 
     channel->outgoing.get_msg_size = red_channel_peer_get_out_msg_size;
     channel->outgoing.prepare = red_channel_peer_prepare_out_msg;
diff --git a/server/red_channel.h b/server/red_channel.h
index 893a7f8..e8ebb05 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -77,6 +77,9 @@ typedef struct OutgoingHandler {
     on_outgoing_error_proc on_error;
     on_outgoing_block_proc on_block;
     on_outgoing_msg_done_proc on_msg_done;
+#ifdef RED_STATISTICS
+    uint64_t *out_bytes_counter;
+#endif
 } OutgoingHandler;
 
 /* Red Channel interface */


More information about the Spice-commits mailing list