diff options
author | Max Kellermann <max@duempel.org> | 2014-06-10 18:57:30 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-06-11 09:27:17 +0200 |
commit | 3364c1b8939aaf2f758a9396d0b73298042516d9 (patch) | |
tree | 046eb528b1e79d8c4bcd55e9939d58bde9981c21 | |
parent | 0801b3f495aac982bc7d009d7ae81d8e3041db0c (diff) |
ClientList: use class boost::intrusive::list
Eliminate extra allocations for the std::list node instances.
-rw-r--r-- | src/client/Client.hxx | 12 | ||||
-rw-r--r-- | src/client/ClientList.cxx | 21 | ||||
-rw-r--r-- | src/client/ClientList.hxx | 13 | ||||
-rw-r--r-- | src/command/MessageCommands.cxx | 8 |
4 files changed, 25 insertions, 29 deletions
diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 56cd947ff..849a11ed4 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -27,6 +27,8 @@ #include "event/TimeoutMonitor.hxx" #include "Compiler.h" +#include <boost/intrusive/list.hpp> + #include <set> #include <string> #include <list> @@ -41,12 +43,20 @@ struct Partition; class Database; class Storage; -class Client final : private FullyBufferedSocket, TimeoutMonitor { +class Client final + : FullyBufferedSocket, TimeoutMonitor, + public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> { public: Partition &partition; struct playlist &playlist; struct PlayerControl &player_control; + struct Disposer { + void operator()(Client *client) const { + delete client; + } + }; + unsigned permission; /** the uid of the client process, or -1 if unknown */ diff --git a/src/client/ClientList.cxx b/src/client/ClientList.cxx index 101802479..a1f286928 100644 --- a/src/client/ClientList.cxx +++ b/src/client/ClientList.cxx @@ -28,28 +28,15 @@ void ClientList::Remove(Client &client) { - assert(size > 0); assert(!list.empty()); - auto i = std::find(list.begin(), list.end(), &client); - assert(i != list.end()); - list.erase(i); - --size; + list.erase(list.iterator_to(client)); } void ClientList::CloseAll() { - while (!list.empty()) { - delete list.front(); - list.pop_front(); - -#ifndef NDEBUG - --size; -#endif - } - - assert(size == 0); + list.clear_and_dispose(Client::Disposer()); } void @@ -57,6 +44,6 @@ ClientList::IdleAdd(unsigned flags) { assert(flags != 0); - for (const auto &client : list) - client->IdleAdd(flags); + for (auto &client : list) + client.IdleAdd(flags); } diff --git a/src/client/ClientList.hxx b/src/client/ClientList.hxx index 4d9a96dcb..7d20a8737 100644 --- a/src/client/ClientList.hxx +++ b/src/client/ClientList.hxx @@ -20,21 +20,21 @@ #ifndef MPD_CLIENT_LIST_HXX #define MPD_CLIENT_LIST_HXX -#include <list> +#include "Client.hxx" class Client; class ClientList { - typedef std::list<Client *> List; + typedef boost::intrusive::list<Client, + boost::intrusive::constant_time_size<true>> List; const unsigned max_size; - unsigned size; List list; public: ClientList(unsigned _max_size) - :max_size(_max_size), size(0) {} + :max_size(_max_size) {} ~ClientList() { CloseAll(); } @@ -48,12 +48,11 @@ public: } bool IsFull() const { - return size >= max_size; + return list.size() >= max_size; } void Add(Client &client) { - list.push_front(&client); - ++size; + list.push_front(client); } void Remove(Client &client); diff --git a/src/command/MessageCommands.cxx b/src/command/MessageCommands.cxx index fe7500aaf..02b251b9a 100644 --- a/src/command/MessageCommands.cxx +++ b/src/command/MessageCommands.cxx @@ -82,8 +82,8 @@ handle_channels(Client &client, std::set<std::string> channels; for (const auto &c : *client.partition.instance.client_list) - channels.insert(c->subscriptions.begin(), - c->subscriptions.end()); + channels.insert(c.subscriptions.begin(), + c.subscriptions.end()); for (const auto &channel : channels) client_printf(client, "channel: %s\n", channel.c_str()); @@ -122,8 +122,8 @@ handle_send_message(Client &client, bool sent = false; const ClientMessage msg(argv[1], argv[2]); - for (const auto &c : *client.partition.instance.client_list) - if (c->PushMessage(msg)) + for (auto &c : *client.partition.instance.client_list) + if (c.PushMessage(msg)) sent = true; if (sent) |