diff --git a/src/ClientInternal.hxx b/src/ClientInternal.hxx index ac50a3e99..be423bb24 100644 --- a/src/ClientInternal.hxx +++ b/src/ClientInternal.hxx @@ -24,6 +24,9 @@ #include "ClientMessage.hxx" #include "command.h" +#include +#include + #include #undef G_LOG_DOMAIN @@ -82,7 +85,7 @@ public: /** * A list of channel names this client is subscribed to. */ - GSList *subscriptions; + std::set subscriptions; /** * The number of subscriptions in #subscriptions. Used to @@ -100,6 +103,11 @@ public: * The number of messages in #messages. */ unsigned num_messages; + + gcc_pure + bool IsSubscribed(const char *channel_name) const { + return subscriptions.find(channel_name) != subscriptions.end(); + } }; extern unsigned int client_max_connections; diff --git a/src/ClientNew.cxx b/src/ClientNew.cxx index 34e782bd2..7bb0c1b10 100644 --- a/src/ClientNew.cxx +++ b/src/ClientNew.cxx @@ -120,7 +120,6 @@ client_new(struct player_control *player_control, client->send_buf_used = 0; - client->subscriptions = NULL; client->messages = NULL; client->num_messages = 0; diff --git a/src/ClientSubscribe.cxx b/src/ClientSubscribe.cxx index 31987c6a0..3f4714958 100644 --- a/src/ClientSubscribe.cxx +++ b/src/ClientSubscribe.cxx @@ -27,17 +27,6 @@ extern "C" { #include -G_GNUC_PURE -static GSList * -client_find_subscription(const Client *client, const char *channel) -{ - for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i)) - if (strcmp((const char *)i->data, channel) == 0) - return i; - - return NULL; -} - enum client_subscribe_result client_subscribe(Client *client, const char *channel) { @@ -47,14 +36,13 @@ client_subscribe(Client *client, const char *channel) if (!client_message_valid_channel_name(channel)) return CLIENT_SUBSCRIBE_INVALID; - if (client_find_subscription(client, channel) != NULL) - return CLIENT_SUBSCRIBE_ALREADY; - if (client->num_subscriptions >= CLIENT_MAX_SUBSCRIPTIONS) return CLIENT_SUBSCRIBE_FULL; - client->subscriptions = g_slist_prepend(client->subscriptions, - g_strdup(channel)); + auto r = client->subscriptions.insert(channel); + if (!r.second) + return CLIENT_SUBSCRIBE_ALREADY; + ++client->num_subscriptions; idle_add(IDLE_SUBSCRIPTION); @@ -65,19 +53,19 @@ client_subscribe(Client *client, const char *channel) bool client_unsubscribe(Client *client, const char *channel) { - GSList *i = client_find_subscription(client, channel); - if (i == NULL) + const auto i = client->subscriptions.find(channel); + if (i == client->subscriptions.end()) return false; assert(client->num_subscriptions > 0); - client->subscriptions = g_slist_remove(client->subscriptions, i->data); + client->subscriptions.erase(i); --client->num_subscriptions; idle_add(IDLE_SUBSCRIPTION); assert((client->num_subscriptions == 0) == - (client->subscriptions == NULL)); + client->subscriptions.empty()); return true; } @@ -85,11 +73,7 @@ client_unsubscribe(Client *client, const char *channel) void client_unsubscribe_all(Client *client) { - for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i)) - g_free(i->data); - - g_slist_free(client->subscriptions); - client->subscriptions = NULL; + client->subscriptions.clear(); client->num_subscriptions = 0; } @@ -101,7 +85,7 @@ client_push_message(Client *client, const struct client_message *msg) assert(client_message_defined(msg)); if (client->num_messages >= CLIENT_MAX_MESSAGES || - client_find_subscription(client, msg->channel) == NULL) + !client->IsSubscribed(msg->channel)) return false; if (client->messages == NULL) diff --git a/src/MessageCommands.cxx b/src/MessageCommands.cxx index 5be179027..6ac5912e7 100644 --- a/src/MessageCommands.cxx +++ b/src/MessageCommands.cxx @@ -83,12 +83,8 @@ collect_channels(gpointer data, gpointer user_data) (struct channels_context *)user_data; const Client *client = (const Client *)data; - for (GSList *i = client->subscriptions; i != NULL; - i = g_slist_next(i)) { - const char *channel = (const char *)i->data; - - context->channels.insert(channel); - } + context->channels.insert(client->subscriptions.begin(), + client->subscriptions.end()); } enum command_return