diff --git a/server/reds-private.h b/server/reds-private.h index 24971cc9f62152608550489900eab0094285cb56..f417f2c66332387f81ab399294c38b7c47027ed8 100644 --- a/server/reds-private.h +++ b/server/reds-private.h @@ -84,7 +84,7 @@ struct RedsState { RedCharDeviceVDIPort *agent_dev; int pending_mouse_event; bool pending_device_display_info_message; - GList *clients; + red::safe_list<RedClient*> clients; MainChannel *main_channel; InputsChannel *inputs_channel; diff --git a/server/reds.cpp b/server/reds.cpp index 15d5431186e439f2d8d5f1b50b34ea9507e6ecdd..bdb966a94dcc4550b9d643d4cc6b96e59ff5492a 100644 --- a/server/reds.cpp +++ b/server/reds.cpp @@ -523,12 +523,12 @@ void reds_client_disconnect(RedsState *reds, RedClient *client) red_char_device_client_remove(reds->agent_dev, client); } - reds->clients = g_list_remove(reds->clients, client); + reds->clients.remove(client); client->destroy(); // 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 (g_list_length(reds->clients) == 0) { + if (reds->clients.empty()) { /* Let the agent know the client is disconnected */ if (reds->agent_dev->priv->agent_attached) { RedCharDeviceWriteBuffer *char_dev_buf = @@ -560,10 +560,8 @@ void reds_client_disconnect(RedsState *reds, RedClient *client) // reds_client_disconnect static void reds_disconnect(RedsState *reds) { - RedClient *client; - spice_debug("trace"); - GLIST_FOREACH(reds->clients, RedClient, client) { + for (auto client: reds->clients) { reds_client_disconnect(reds, client); } reds_mig_cleanup(reds); @@ -1005,7 +1003,7 @@ void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mou SPICE_GNUC_VISIBLE int spice_server_get_num_clients(SpiceServer *reds) { - return reds ? g_list_length(reds->clients) : 0; + return reds ? reds->clients.size() : 0; } static bool channel_supports_multiple_clients(RedChannel *channel) @@ -1025,7 +1023,7 @@ static void reds_fill_channels(RedsState *reds, SpiceMsgChannels *channels_info) int used_channels = 0; for (const auto channel: reds->channels) { - if (g_list_length(reds->clients) > 1 && + if (reds->clients.size() > 1 && !channel_supports_multiple_clients(channel)) { continue; } @@ -1284,7 +1282,7 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc) RedCharDeviceVDIPort *agent_dev = reds->agent_dev; uint32_t read_data_len; - spice_assert(g_list_length(reds->clients) == 1); + spice_assert(reds->clients.size() == 1); if (agent_dev->priv->read_state != VDI_PORT_READ_STATE_READ_DATA) { return; @@ -1752,9 +1750,7 @@ static void reds_mig_target_client_disconnect_all(RedsState *reds) static bool reds_find_client(RedsState *reds, RedClient *client) { - RedClient *list_client; - - GLIST_FOREACH(reds->clients, RedClient, list_client) { + for (auto list_client: reds->clients) { if (list_client == client) { return TRUE; } @@ -1765,14 +1761,13 @@ static bool reds_find_client(RedsState *reds, RedClient *client) /* should be used only when there is one client */ static RedClient *reds_get_client(RedsState *reds) { - gint n = g_list_length(reds->clients); - spice_assert(n <= 1); + spice_assert(reds->clients.size() <= 1); - if (n == 0) { + if (reds->clients.empty()) { return NULL; } - return (RedClient*) reds->clients->data; + return *reds->clients.begin(); } /* Performs late initializations steps. @@ -1855,7 +1850,7 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link) stream = link->stream; link->stream = NULL; client = red_client_new(reds, mig_target); - reds->clients = g_list_prepend(reds->clients, client); + reds->clients.push_front(client); red_channel_capabilities_init_from_link_message(&caps, link_mess); mcc = main_channel_link(reds->main_channel, client, @@ -2994,12 +2989,10 @@ static void reds_mig_started(RedsState *reds) static void reds_mig_fill_wait_disconnect(RedsState *reds) { - RedClient *client; - - spice_assert(reds->clients != NULL); + spice_assert(!reds->clients.empty()); /* tracking the clients, in order to ignore disconnection * of clients that got connected to the src after migration completion.*/ - GLIST_FOREACH(reds->clients, RedClient, client) { + for (auto client: reds->clients) { reds->mig_wait_disconnect_clients = g_list_append(reds->mig_wait_disconnect_clients, client); } reds->mig_wait_connect = FALSE; @@ -3440,7 +3433,6 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface) reds->core.public_interface = core_interface; reds->agent_dev = red_char_device_vdi_port_new(reds); reds_update_agent_properties(reds); - reds->clients = NULL; reds->main_dispatcher = new MainDispatcher(reds); reds->mig_target_clients = NULL; reds->mig_wait_disconnect_clients = NULL; @@ -4230,7 +4222,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *reds, const cha if (reds->main_channel->migrate_connect(reds->config->mig_spice, try_seamless)) { reds_mig_started(reds); } else { - if (reds->clients == NULL) { + if (reds->clients.empty()) { reds_mig_release(reds->config); spice_debug("no client connected"); } @@ -4272,7 +4264,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_end(SpiceServer *reds, int completed spice_assert(reds->migration_interface); sif = SPICE_UPCAST(SpiceMigrateInterface, reds->migration_interface->base.sif); - if (completed && !reds->expect_migrate && g_list_length(reds->clients) > 0) { + if (completed && !reds->expect_migrate && !reds->clients.empty()) { spice_warning("spice_server_migrate_info was not called, disconnecting clients"); reds_disconnect(reds); ret = -1; @@ -4297,7 +4289,7 @@ complete: SPICE_GNUC_VISIBLE int spice_server_migrate_switch(SpiceServer *reds) { spice_debug("trace"); - if (reds->clients == NULL) { + if (reds->clients.empty()) { return 0; } reds->expect_migrate = FALSE;