aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-01-16 22:55:33 +0100
committerMax Kellermann <max@duempel.org>2013-01-16 23:00:13 +0100
commit601495fa0f3d3793d4ee761d1b86f8435417266c (patch)
tree1284f0f0ac48668391063e5f45eba08d0b59c2ed
parent1998633739b027b97ff89f92825512db91dca8f9 (diff)
downloadmpd-601495fa0f3d3793d4ee761d1b86f8435417266c.tar.gz
mpd-601495fa0f3d3793d4ee761d1b86f8435417266c.tar.xz
mpd-601495fa0f3d3793d4ee761d1b86f8435417266c.zip
ClientList: convert to a class
-rw-r--r--Makefile.am2
-rw-r--r--src/Client.hxx1
-rw-r--r--src/ClientGlobal.cxx13
-rw-r--r--src/ClientIdle.cxx17
-rw-r--r--src/ClientIdle.hxx30
-rw-r--r--src/ClientInternal.hxx1
-rw-r--r--src/ClientList.cxx45
-rw-r--r--src/ClientList.hxx41
-rw-r--r--src/ClientNew.cxx7
-rw-r--r--src/ClientSubscribe.cxx1
-rw-r--r--src/Main.cxx11
-rw-r--r--src/Main.hxx2
-rw-r--r--src/MessageCommands.cxx55
13 files changed, 73 insertions, 153 deletions
diff --git a/Makefile.am b/Makefile.am
index cf41e3ddd..6871f2085 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -222,7 +222,7 @@ src_mpd_SOURCES = \
src/ClientEvent.cxx \
src/ClientExpire.cxx \
src/ClientGlobal.cxx \
- src/ClientIdle.cxx src/ClientIdle.hxx \
+ src/ClientIdle.cxx \
src/ClientList.cxx src/ClientList.hxx \
src/ClientNew.cxx \
src/ClientProcess.cxx \
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 <assert.h>
#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 <assert.h>
@@ -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 <list>
#include <algorithm>
#include <assert.h>
-static std::list<Client *> 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 <list>
+
class Client;
-bool
-client_list_is_full(void);
+class ClientList {
+ const unsigned max_size;
+
+ unsigned size;
+ std::list<Client *> list;
+
+public:
+ ClientList(unsigned _max_size)
+ :max_size(_max_size), size(0) {}
+
+ std::list<Client *>::iterator begin() {
+ return list.begin();
+ }
+
+ std::list<Client *>::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<std::string> 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<std::string> 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<typename T, typename U>
- send_message_context(T &&_channel, U &&_message)
- :msg(std::forward<T>(_channel), std::forward<U>(_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,