From 601495fa0f3d3793d4ee761d1b86f8435417266c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Jan 2013 22:55:33 +0100 Subject: ClientList: convert to a class --- src/Client.hxx | 1 - src/ClientGlobal.cxx | 13 ------------ src/ClientIdle.cxx | 17 --------------- src/ClientIdle.hxx | 30 --------------------------- src/ClientInternal.hxx | 1 - src/ClientList.cxx | 45 ++++++++++++++-------------------------- src/ClientList.hxx | 41 +++++++++++++++++++++++++++--------- src/ClientNew.cxx | 7 ++++--- src/ClientSubscribe.cxx | 1 - src/Main.cxx | 11 +++++++--- src/Main.hxx | 2 ++ src/MessageCommands.cxx | 55 +++++++++++-------------------------------------- 12 files changed, 72 insertions(+), 152 deletions(-) delete mode 100644 src/ClientIdle.hxx (limited to 'src') diff --git a/src/Client.hxx b/src/Client.hxx index bf2a2521f..1456f1b7d 100644 --- a/src/Client.hxx +++ b/src/Client.hxx @@ -31,7 +31,6 @@ struct Partition; class Client; void client_manager_init(void); -void client_manager_deinit(void); void client_new(EventLoop &loop, Partition &partition, diff --git a/src/ClientGlobal.cxx b/src/ClientGlobal.cxx index 2ce2d3839..6115a7856 100644 --- a/src/ClientGlobal.cxx +++ b/src/ClientGlobal.cxx @@ -25,12 +25,9 @@ #include #define CLIENT_TIMEOUT_DEFAULT (60) -#define CLIENT_MAX_CONNECTIONS_DEFAULT (10) #define CLIENT_MAX_COMMAND_LIST_DEFAULT (2048*1024) #define CLIENT_MAX_OUTPUT_BUFFER_SIZE_DEFAULT (8192*1024) -/* set this to zero to indicate we have no possible clients */ -unsigned int client_max_connections; int client_timeout; size_t client_max_command_list_size; size_t client_max_output_buffer_size; @@ -39,9 +36,6 @@ void client_manager_init(void) { client_timeout = config_get_positive(CONF_CONN_TIMEOUT, CLIENT_TIMEOUT_DEFAULT); - client_max_connections = - config_get_positive(CONF_MAX_CONN, - CLIENT_MAX_CONNECTIONS_DEFAULT); client_max_command_list_size = config_get_positive(CONF_MAX_COMMAND_LIST_SIZE, CLIENT_MAX_COMMAND_LIST_DEFAULT / 1024) @@ -52,10 +46,3 @@ void client_manager_init(void) CLIENT_MAX_OUTPUT_BUFFER_SIZE_DEFAULT / 1024) * 1024; } - -void client_manager_deinit(void) -{ - client_list_close_all(); - - client_max_connections = 0; -} diff --git a/src/ClientIdle.cxx b/src/ClientIdle.cxx index 89cb10aa1..714438123 100644 --- a/src/ClientIdle.cxx +++ b/src/ClientIdle.cxx @@ -18,9 +18,7 @@ */ #include "config.h" -#include "ClientIdle.hxx" #include "ClientInternal.hxx" -#include "ClientList.hxx" #include "Idle.hxx" #include @@ -58,21 +56,6 @@ Client::IdleAdd(unsigned flags) IdleNotify(); } -static void -client_idle_callback(Client *client, gpointer user_data) -{ - unsigned flags = GPOINTER_TO_UINT(user_data); - - client->IdleAdd(flags); -} - -void client_manager_idle_add(unsigned flags) -{ - assert(flags != 0); - - client_list_foreach(client_idle_callback, GUINT_TO_POINTER(flags)); -} - bool Client::IdleWait(unsigned flags) { diff --git a/src/ClientIdle.hxx b/src/ClientIdle.hxx deleted file mode 100644 index eb0efd1bf..000000000 --- a/src/ClientIdle.hxx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2003-2013 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPD_CLIENT_IDLE_HXX -#define MPD_CLIENT_IDLE_HXX - -/** - * Adds the specified idle flags to all clients and immediately sends - * notifications to all waiting clients. - */ -void -client_manager_idle_add(unsigned flags); - -#endif diff --git a/src/ClientInternal.hxx b/src/ClientInternal.hxx index 097029f0b..d538cfb37 100644 --- a/src/ClientInternal.hxx +++ b/src/ClientInternal.hxx @@ -125,7 +125,6 @@ private: virtual bool OnTimeout() override; }; -extern unsigned int client_max_connections; extern int client_timeout; extern size_t client_max_command_list_size; extern size_t client_max_output_buffer_size; diff --git a/src/ClientList.cxx b/src/ClientList.cxx index bfa04fea1..37e6f1289 100644 --- a/src/ClientList.cxx +++ b/src/ClientList.cxx @@ -21,51 +21,36 @@ #include "ClientList.hxx" #include "ClientInternal.hxx" -#include #include #include -static std::list clients; -static unsigned num_clients; - -bool -client_list_is_full(void) -{ - return num_clients >= client_max_connections; -} - void -client_list_add(Client *client) +ClientList::Remove(Client &client) { - clients.push_front(client); - ++num_clients; -} + assert(size > 0); + assert(!list.empty()); -void -client_list_foreach(void (*callback)(Client *client, void *ctx), void *ctx) -{ - for (Client *client : clients) - callback(client, ctx); + auto i = std::find(list.begin(), list.end(), &client); + assert(i != list.end()); + list.erase(i); + --size; } void -client_list_remove(Client *client) +ClientList::CloseAll() { - assert(num_clients > 0); - assert(!clients.empty()); + while (!list.empty()) + list.front()->Close(); - auto i = std::find(clients.begin(), clients.end(), client); - assert(i != clients.end()); - clients.erase(i); - --num_clients; + assert(size == 0); } void -client_list_close_all() +ClientList::IdleAdd(unsigned flags) { - while (!clients.empty()) - clients.front()->Close(); + assert(flags != 0); - assert(num_clients == 0); + for (const auto &client : list) + client->IdleAdd(flags); } diff --git a/src/ClientList.hxx b/src/ClientList.hxx index a5a89ceea..e8560af78 100644 --- a/src/ClientList.hxx +++ b/src/ClientList.hxx @@ -20,21 +20,42 @@ #ifndef MPD_CLIENT_LIST_HXX #define MPD_CLIENT_LIST_HXX +#include + class Client; -bool -client_list_is_full(void); +class ClientList { + const unsigned max_size; + + unsigned size; + std::list list; + +public: + ClientList(unsigned _max_size) + :max_size(_max_size), size(0) {} + + std::list::iterator begin() { + return list.begin(); + } + + std::list::iterator end() { + return list.end(); + } + + bool IsFull() const { + return size >= max_size; + } -void -client_list_add(Client *client); + void Add(Client &client) { + list.push_front(&client); + ++size; + } -void -client_list_foreach(void (*callback)(Client *client, void *ctx), void *ctx); + void Remove(Client &client); -void -client_list_remove(Client *client); + void CloseAll(); -void -client_list_close_all(); + void IdleAdd(unsigned flags); +}; #endif diff --git a/src/ClientNew.cxx b/src/ClientNew.cxx index 2a4774c55..74cb0cc8d 100644 --- a/src/ClientNew.cxx +++ b/src/ClientNew.cxx @@ -21,6 +21,7 @@ #include "ClientInternal.hxx" #include "ClientList.hxx" #include "Partition.hxx" +#include "Main.hxx" #include "fd_util.h" extern "C" { #include "resolver.h" @@ -95,7 +96,7 @@ client_new(EventLoop &loop, Partition &partition, } #endif /* HAVE_WRAP */ - if (client_list_is_full()) { + if (client_list->IsFull()) { g_warning("Max Connections Reached!"); close_socket(fd); return; @@ -106,7 +107,7 @@ client_new(EventLoop &loop, Partition &partition, (void)send(fd, GREETING, sizeof(GREETING) - 1, 0); - client_list_add(client); + client_list->Add(*client); remote = sockaddr_to_string(sa, sa_length, NULL); g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE, @@ -117,7 +118,7 @@ client_new(EventLoop &loop, Partition &partition, void Client::Close() { - client_list_remove(this); + client_list->Remove(*this); SetExpired(); diff --git a/src/ClientSubscribe.cxx b/src/ClientSubscribe.cxx index 307d44990..918a621db 100644 --- a/src/ClientSubscribe.cxx +++ b/src/ClientSubscribe.cxx @@ -19,7 +19,6 @@ #include "config.h" #include "ClientSubscribe.hxx" -#include "ClientIdle.hxx" #include "ClientInternal.hxx" #include "Idle.hxx" diff --git a/src/Main.cxx b/src/Main.cxx index 917d89457..e70e5f908 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -31,8 +31,8 @@ #include "DatabaseSimple.hxx" #include "Permission.hxx" #include "Listen.hxx" -#include "ClientIdle.hxx" #include "Client.hxx" +#include "ClientList.hxx" #include "AllCommands.hxx" #include "Partition.hxx" #include "Volume.hxx" @@ -99,6 +99,8 @@ enum { GThread *main_task; EventLoop *main_loop; +ClientList *client_list; + Partition *global_partition; static StateFile *state_file; @@ -330,7 +332,7 @@ idle_event_emitted(void) clients */ unsigned flags = idle_get(); if (flags != 0) - client_manager_idle_add(flags); + client_list->IdleAdd(flags); } /** @@ -401,6 +403,9 @@ int mpd_main(int argc, char *argv[]) main_task = g_thread_self(); main_loop = new EventLoop(EventLoop::Default()); + const unsigned max_clients = config_get_positive(CONF_MAX_CONN, 10); + client_list = new ClientList(max_clients); + success = listen_global_init(&error); if (!success) { g_warning("%s", error->message); @@ -532,8 +537,8 @@ int mpd_main(int argc, char *argv[]) pc_kill(&global_partition->pc); finishZeroconf(); - client_manager_deinit(); listen_global_finish(); + delete client_list; start = clock(); DatabaseGlobalDeinit(); diff --git a/src/Main.hxx b/src/Main.hxx index 6ce079434..b2768600c 100644 --- a/src/Main.hxx +++ b/src/Main.hxx @@ -28,6 +28,8 @@ extern GThread *main_task; extern EventLoop *main_loop; +extern class ClientList *client_list; + extern struct Partition *global_partition; /** diff --git a/src/MessageCommands.cxx b/src/MessageCommands.cxx index 6a967f95b..f19a1b5d4 100644 --- a/src/MessageCommands.cxx +++ b/src/MessageCommands.cxx @@ -22,6 +22,7 @@ #include "ClientSubscribe.hxx" #include "ClientInternal.hxx" #include "ClientList.hxx" +#include "Main.hxx" #include "protocol/Result.hxx" #include "protocol/ArgParser.hxx" @@ -73,31 +74,18 @@ handle_unsubscribe(Client *client, G_GNUC_UNUSED int argc, char *argv[]) } } -struct channels_context { - std::set channels; -}; - -static void -collect_channels(Client *client, gpointer user_data) -{ - struct channels_context *context = - (struct channels_context *)user_data; - - context->channels.insert(client->subscriptions.begin(), - client->subscriptions.end()); -} - enum command_return handle_channels(Client *client, G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[]) { assert(argc == 1); - struct channels_context context; - - client_list_foreach(collect_channels, &context); + std::set channels; + for (const auto &c : *client_list) + channels.insert(c->subscriptions.begin(), + c->subscriptions.end()); - for (const auto &channel : context.channels) + for (const auto &channel : channels) client_printf(client, "channel: %s\n", channel.c_str()); return COMMAND_RETURN_OK; @@ -120,27 +108,6 @@ handle_read_messages(Client *client, return COMMAND_RETURN_OK; } -struct send_message_context { - ClientMessage msg; - - bool sent; - - template - send_message_context(T &&_channel, U &&_message) - :msg(std::forward(_channel), std::forward(_message)), - sent(false) {} -}; - -static void -send_message(Client *client, gpointer user_data) -{ - struct send_message_context *context = - (struct send_message_context *)user_data; - - if (client_push_message(client, context->msg)) - context->sent = true; -} - enum command_return handle_send_message(Client *client, G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[]) @@ -153,11 +120,13 @@ handle_send_message(Client *client, return COMMAND_RETURN_ERROR; } - struct send_message_context context(argv[1], argv[2]); - - client_list_foreach(send_message, &context); + bool sent = false; + const ClientMessage msg(argv[1], argv[2]); + for (const auto &c : *client_list) + if (client_push_message(c, msg)) + sent = true; - if (context.sent) + if (sent) return COMMAND_RETURN_OK; else { command_error(client, ACK_ERROR_NO_EXIST, -- cgit v1.2.3