From 3364c1b8939aaf2f758a9396d0b73298042516d9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 10 Jun 2014 18:57:30 +0200 Subject: [PATCH] ClientList: use class boost::intrusive::list Eliminate extra allocations for the std::list node instances. --- src/client/Client.hxx | 12 +++++++++++- src/client/ClientList.cxx | 21 ++++----------------- src/client/ClientList.hxx | 13 ++++++------- 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 + #include #include #include @@ -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> { 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 +#include "Client.hxx" class Client; class ClientList { - typedef std::list List; + typedef boost::intrusive::list> 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 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)