summaryrefslogtreecommitdiffstats
path: root/server/main_channel.c
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-04-11 12:44:00 +0300
committerAlon Levy <alevy@redhat.com>2011-08-23 17:56:44 +0300
commit448ed75bd6c8db7ca48cab8aa1256a262e87fcc0 (patch)
tree653fa73b47966052cc0cec9184090c0b3349fc89 /server/main_channel.c
parent22084c4703282699a34dfb72f3c6318159ddcedf (diff)
downloadspice-448ed75bd6c8db7ca48cab8aa1256a262e87fcc0.tar.gz
spice-448ed75bd6c8db7ca48cab8aa1256a262e87fcc0.tar.xz
spice-448ed75bd6c8db7ca48cab8aa1256a262e87fcc0.zip
server: Add RedClient
That means RedClient tracks a ring of channels. Right now there will be only a single client because of the disconnection mechanism - whenever a new client comes we disconnect all existing clients. But this patch adds already a ring of clients to reds.c (stored in RedServer). There is a known problem handling many connections and disconnections at the same time, trigerrable easily by the following script: export NEW_DISPLAY=:3.0 Xephyr $NEW_DISPLAY -noreset & for ((i = 0 ; i < 5; ++i)); do for ((j = 0 ; j < 10; ++j)); do DISPLAY=$NEW_DISPLAY c_win7x86_qxl_tests & done sleep 2; done I fixed a few of the problems resulting from this in the same patch. This required already introducing a few other changes: * make sure all removal of channels happens in the main thread, for that two additional dispatcher calls are added to remove a specific channel client (RED_WORKER_MESSAGE_CURSOR_DISCONNECT_CLIENT and RED_WORKER_MESSAGE_DISPLAY_DISCONNECT_CLIENT). * change some asserts in input channel. * make main channel disconnect not recursive * introduce disconnect call back to red_channel_create_parser The remaining abort is from a double free in the main channel, still can't find it (doesn't happen when running under valgrind - probably due to the slowness resulting from that), but is easy to see when running under gdb.
Diffstat (limited to 'server/main_channel.c')
-rw-r--r--server/main_channel.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/server/main_channel.c b/server/main_channel.c
index a7f53e46..978cdb31 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -139,6 +139,11 @@ enum NetTestStage {
static uint64_t latency = 0;
uint64_t bitrate_per_sec = ~0;
+static void main_channel_client_disconnect(RedChannelClient *rcc)
+{
+ red_channel_client_disconnect(rcc);
+}
+
static void main_disconnect(MainChannel *main_chan)
{
red_channel_destroy(&main_chan->base);
@@ -788,7 +793,7 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
static void main_channel_on_error(RedChannelClient *rcc)
{
- reds_disconnect();
+ reds_client_disconnect(rcc->client);
}
static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header)
@@ -819,19 +824,20 @@ static int main_channel_handle_migrate_flush_mark(RedChannelClient *rcc)
return TRUE;
}
-MainChannelClient *main_channel_link(Channel *channel, RedsStream *stream, int migration,
+MainChannelClient *main_channel_link(Channel *channel, RedClient *client,
+ RedsStream *stream, int migration,
int num_common_caps, uint32_t *common_caps, int num_caps,
uint32_t *caps)
{
MainChannel *main_chan;
MainChannelClient *mcc;
- ASSERT(channel->data == NULL);
if (channel->data == NULL) {
red_printf("create main channel");
channel->data = red_channel_create_parser(
sizeof(*main_chan), core, migration, FALSE /* handle_acks */
,main_channel_config_socket
+ ,main_channel_client_disconnect
,spice_get_client_channel_parser(SPICE_CHANNEL_MAIN, NULL)
,main_channel_handle_parsed
,main_channel_alloc_msg_rcv_buf
@@ -849,7 +855,7 @@ MainChannelClient *main_channel_link(Channel *channel, RedsStream *stream, int m
main_chan = (MainChannel*)channel->data;
red_printf("add main channel client");
mcc = (MainChannelClient*)
- red_channel_client_create(sizeof(MainChannelClient), &main_chan->base, stream);
+ red_channel_client_create(sizeof(MainChannelClient), &main_chan->base, client, stream);
return mcc;
}