summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-06-10 18:57:30 +0200
committerMax Kellermann <max@duempel.org>2014-06-11 09:27:17 +0200
commit3364c1b8939aaf2f758a9396d0b73298042516d9 (patch)
tree046eb528b1e79d8c4bcd55e9939d58bde9981c21
parent0801b3f495aac982bc7d009d7ae81d8e3041db0c (diff)
ClientList: use class boost::intrusive::list
Eliminate extra allocations for the std::list node instances.
-rw-r--r--src/client/Client.hxx12
-rw-r--r--src/client/ClientList.cxx21
-rw-r--r--src/client/ClientList.hxx13
-rw-r--r--src/command/MessageCommands.cxx8
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)