[Spice-devel] [PATCH 2/4] Convert RedsState::clients to GList
Jonathon Jongsma
jjongsma at redhat.com
Wed Oct 26 19:47:34 UTC 2016
Switch from a Ring to a GList so that we can hide the internals of
RedClient in a future commit.
---
server/red-channel.h | 1 -
server/reds-private.h | 3 +--
server/reds.c | 54 ++++++++++++++++++++++++---------------------------
3 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/server/red-channel.h b/server/red-channel.h
index 1b46c01..528babc 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -328,7 +328,6 @@ const RedChannelCapabilities* red_channel_get_local_capabilities(RedChannel *sel
struct RedClient {
RedsState *reds;
- RingItem link;
GList *channels;
MainChannelClient *mcc;
pthread_mutex_t lock; // different channels can be in different threads
diff --git a/server/reds-private.h b/server/reds-private.h
index cc13ba7..ce78945 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -94,8 +94,7 @@ struct RedsState {
SpiceWatch *secure_listen_watch;
RedCharDeviceVDIPort *agent_dev;
int pending_mouse_event;
- Ring clients;
- int num_clients;
+ GList *clients;
MainChannel *main_channel;
InputsChannel *inputs_channel;
diff --git a/server/reds.c b/server/reds.c
index de0d356..90437c0 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -595,13 +595,12 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
red_char_device_client_remove(RED_CHAR_DEVICE(reds->agent_dev), client);
}
- ring_remove(&client->link);
- reds->num_clients--;
+ reds->clients = g_list_remove(reds->clients, client);
red_client_destroy(client);
// TODO: we need to handle agent properly for all clients!!!! (e.g., cut and paste, how? Maybe throw away messages
// if we are in the middle of one from another client)
- if (reds->num_clients == 0) {
+ if (g_list_length(reds->clients) == 0) {
/* Let the agent know the client is disconnected */
if (reds->agent_dev->priv->agent_attached) {
RedCharDeviceWriteBuffer *char_dev_buf;
@@ -644,11 +643,12 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
// reds_client_disconnect
static void reds_disconnect(RedsState *reds)
{
- RingItem *link, *next;
+ GListIter iter;
+ RedClient *client;
spice_info(NULL);
- RING_FOREACH_SAFE(link, next, &reds->clients) {
- reds_client_disconnect(reds, SPICE_CONTAINEROF(link, RedClient, link));
+ GLIST_FOREACH(reds->clients, iter, RedClient, client) {
+ reds_client_disconnect(reds, client);
}
reds_mig_cleanup(reds);
}
@@ -973,7 +973,7 @@ void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mou
static int reds_get_n_clients(RedsState *reds)
{
- return reds ? reds->num_clients : 0;
+ return reds ? g_list_length(reds->clients) : 0;
}
SPICE_GNUC_VISIBLE int spice_server_get_num_clients(SpiceServer *reds)
@@ -1003,7 +1003,7 @@ static void reds_fill_channels(RedsState *reds, SpiceMsgChannels *channels_info)
GLIST_FOREACH(reds->channels, it, RedChannel, channel) {
uint32_t type, id;
- if (reds->num_clients > 1 &&
+ if (g_list_length(reds->clients) > 1 &&
!channel_supports_multiple_clients(channel)) {
continue;
}
@@ -1245,7 +1245,7 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc)
RedCharDeviceVDIPort *agent_dev = reds->agent_dev;
uint32_t read_data_len;
- spice_assert(reds->num_clients == 1);
+ spice_assert(g_list_length(reds->clients) == 1);
if (agent_dev->priv->read_state != VDI_PORT_READ_STATE_READ_DATA) {
return;
@@ -1718,12 +1718,10 @@ static void reds_mig_target_client_disconnect_all(RedsState *reds)
static int reds_find_client(RedsState *reds, RedClient *client)
{
- RingItem *item;
-
- RING_FOREACH(item, &reds->clients) {
- RedClient *list_client;
+ GListIter iter;
+ RedClient *list_client;
- list_client = SPICE_CONTAINEROF(item, RedClient, link);
+ GLIST_FOREACH(reds->clients, iter, RedClient, list_client) {
if (list_client == client) {
return TRUE;
}
@@ -1734,13 +1732,14 @@ static int reds_find_client(RedsState *reds, RedClient *client)
/* should be used only when there is one client */
static RedClient *reds_get_client(RedsState *reds)
{
- spice_assert(reds->num_clients <= 1);
+ gint n = g_list_length(reds->clients);
+ spice_assert(n <= 1);
- if (reds->num_clients == 0) {
+ if (n == 0) {
return NULL;
}
- return SPICE_CONTAINEROF(ring_get_head(&reds->clients), RedClient, link);
+ return reds->clients->data;
}
// TODO: now that main is a separate channel this should
@@ -1787,8 +1786,7 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link)
reds_link_free(link);
caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset);
client = red_client_new(reds, mig_target);
- ring_add(&reds->clients, &client->link);
- reds->num_clients++;
+ reds->clients = g_list_prepend(reds->clients, client);
mcc = main_channel_link(reds->main_channel, client,
stream, connection_id, mig_target,
link_mess->num_common_caps,
@@ -2983,14 +2981,13 @@ static void reds_mig_started(RedsState *reds)
static void reds_mig_fill_wait_disconnect(RedsState *reds)
{
- RingItem *client_item;
+ GListIter iter;
+ RedClient *client;
- spice_assert(reds->num_clients > 0);
+ spice_assert(reds->clients != NULL);
/* tracking the clients, in order to ignore disconnection
* of clients that got connected to the src after migration completion.*/
- RING_FOREACH(client_item, &reds->clients) {
- RedClient *client = SPICE_CONTAINEROF(client_item, RedClient, link);
-
+ GLIST_FOREACH(reds->clients, iter, RedClient, client) {
reds->mig_wait_disconnect_clients = g_list_append(reds->mig_wait_disconnect_clients, client);
}
reds->mig_wait_connect = FALSE;
@@ -3431,8 +3428,7 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
reds->secure_listen_socket = -1;
reds->agent_dev = red_char_device_vdi_port_new(reds);
reds_update_agent_properties(reds);
- ring_init(&reds->clients);
- reds->num_clients = 0;
+ reds->clients = NULL;
reds->main_dispatcher = main_dispatcher_new(reds, reds->core);
reds->channels = NULL;
reds->mig_target_clients = NULL;
@@ -4101,7 +4097,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *reds, const cha
try_seamless)) {
reds_mig_started(reds);
} else {
- if (reds->num_clients == 0) {
+ if (reds->clients == NULL) {
reds_mig_release(reds);
spice_info("no client connected");
}
@@ -4143,7 +4139,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_end(SpiceServer *reds, int completed
spice_assert(reds->migration_interface);
sif = SPICE_CONTAINEROF(reds->migration_interface->base.sif, SpiceMigrateInterface, base);
- if (completed && !reds->expect_migrate && reds->num_clients) {
+ if (completed && !reds->expect_migrate && g_list_length(reds->clients) > 0) {
spice_warning("spice_server_migrate_info was not called, disconnecting clients");
reds_disconnect(reds);
ret = -1;
@@ -4168,7 +4164,7 @@ complete:
SPICE_GNUC_VISIBLE int spice_server_migrate_switch(SpiceServer *reds)
{
spice_info(NULL);
- if (!reds->num_clients) {
+ if (reds->clients == NULL) {
return 0;
}
reds->expect_migrate = FALSE;
--
2.7.4
More information about the Spice-devel
mailing list