diff options
author | Alon Levy <alevy@redhat.com> | 2011-04-11 12:44:00 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-08-23 17:56:44 +0300 |
commit | 448ed75bd6c8db7ca48cab8aa1256a262e87fcc0 (patch) | |
tree | 653fa73b47966052cc0cec9184090c0b3349fc89 /server/main_channel.c | |
parent | 22084c4703282699a34dfb72f3c6318159ddcedf (diff) | |
download | spice-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.c | 14 |
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; } |