diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2011-08-03 16:04:20 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-08-23 18:23:48 +0300 |
commit | 1db936e64cfe955a757d9d77302f104f68a58bfd (patch) | |
tree | 8c8ae75a9c9116b37398ef97f625c1f180b15d2a /server/red_channel.c | |
parent | 812d01c06090f14ccb65e9a3b81df311c51e4b26 (diff) | |
download | spice-1db936e64cfe955a757d9d77302f104f68a58bfd.tar.gz spice-1db936e64cfe955a757d9d77302f104f68a58bfd.tar.xz spice-1db936e64cfe955a757d9d77302f104f68a58bfd.zip |
server/red_channel.c inroducing client_cbs
client_cbs are supposed to be called from client context (reds). This patch will be used
in future patches for relacing reds::Channel with RedChannel in order to eliminate redundancy.
Diffstat (limited to 'server/red_channel.c')
-rw-r--r-- | server/red_channel.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/server/red_channel.c b/server/red_channel.c index e31f1481..80aa667c 100644 --- a/server/red_channel.c +++ b/server/red_channel.c @@ -417,6 +417,24 @@ error: return NULL; } +static void red_channel_client_default_connect(RedChannel *channel, RedClient *client, + RedsStream *stream, + int migration, + int num_common_caps, uint32_t *common_caps, + int num_caps, uint32_t *caps) +{ + red_error("not implemented"); +} + +static void red_channel_client_default_disconnect(RedChannelClient *base) +{ + red_channel_client_disconnect(base); +} + +static void red_channel_client_default_migrate(RedChannelClient *base) +{ +} + RedChannel *red_channel_create(int size, SpiceCoreInterface *core, int migrate, int handle_acks, @@ -424,6 +442,7 @@ RedChannel *red_channel_create(int size, ChannelCbs *channel_cbs) { RedChannel *channel; + ClientCbs client_cbs; ASSERT(size >= sizeof(*channel)); ASSERT(channel_cbs->config_socket && channel_cbs->disconnect && handle_message && @@ -457,6 +476,14 @@ RedChannel *red_channel_create(int size, channel->outgoing_cb.on_msg_done = red_channel_peer_on_out_msg_done; channel->outgoing_cb.on_output = red_channel_client_on_output; + client_cbs.connect = red_channel_client_default_connect; + client_cbs.disconnect = red_channel_client_default_disconnect; + client_cbs.migrate = red_channel_client_default_migrate; + + red_channel_register_client_cbs(channel, &client_cbs); + + channel->thread_id = pthread_self(); + channel->shut = 0; // came here from inputs, perhaps can be removed? XXX channel->out_bytes_counter = 0; return channel; @@ -492,6 +519,20 @@ RedChannel *red_channel_create_parser(int size, return channel; } +void red_channel_register_client_cbs(RedChannel *channel, ClientCbs *client_cbs) +{ + ASSERT(client_cbs->connect); + channel->client_cbs.connect = client_cbs->connect; + + if (client_cbs->disconnect) { + channel->client_cbs.disconnect = client_cbs->disconnect; + } + + if (client_cbs->migrate) { + channel->client_cbs.migrate = client_cbs->migrate; + } +} + void red_channel_client_destroy(RedChannelClient *rcc) { red_channel_client_disconnect(rcc); @@ -1102,6 +1143,8 @@ RedClient *red_client_new() client = spice_malloc0(sizeof(RedClient)); ring_init(&client->channels); + client->thread_id = pthread_self(); + return client; } @@ -1121,11 +1164,17 @@ void red_client_destroy(RedClient *client) RedChannelClient *rcc; red_printf("destroy client with #channels %d", client->channels_num); + ASSERT(pthread_equal(pthread_self(), client->thread_id)); RING_FOREACH_SAFE(link, next, &client->channels) { // some channels may be in other threads, so disconnection // is not synchronous. rcc = SPICE_CONTAINEROF(link, RedChannelClient, client_link); - rcc->channel->channel_cbs.disconnect(rcc); // this may call another thread. it also frees. (eventually - doesn't have to be in sync) + // some channels may be in other threads. However we currently + // assume disconnect is synchronous (we changed the dispatcher + // to wait for disconnection) + // TODO: should we go back to async. For this we need to use + // ref count for channel clients. + rcc->channel->client_cbs.disconnect(rcc); } free(client); } @@ -1140,7 +1189,7 @@ void red_client_disconnect(RedClient *client) // some channels may be in other threads, so disconnection // is not synchronous. rcc = SPICE_CONTAINEROF(link, RedChannelClient, client_link); - rcc->channel->channel_cbs.disconnect(rcc); + rcc->channel->client_cbs.disconnect(rcc); } } |