aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/output/plugins/httpd/HttpdClient.hxx6
-rw-r--r--src/output/plugins/httpd/HttpdInternal.hxx12
-rw-r--r--src/output/plugins/httpd/HttpdOutputPlugin.cxx25
3 files changed, 18 insertions, 25 deletions
diff --git a/src/output/plugins/httpd/HttpdClient.hxx b/src/output/plugins/httpd/HttpdClient.hxx
index 7bd265bd8..6646ddf4c 100644
--- a/src/output/plugins/httpd/HttpdClient.hxx
+++ b/src/output/plugins/httpd/HttpdClient.hxx
@@ -23,6 +23,8 @@
#include "event/BufferedSocket.hxx"
#include "Compiler.h"
+#include <boost/intrusive/list.hpp>
+
#include <queue>
#include <list>
@@ -31,7 +33,9 @@
class HttpdOutput;
class Page;
-class HttpdClient final : BufferedSocket {
+class HttpdClient final
+ : BufferedSocket,
+ public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
/**
* The httpd output object this client is connected to.
*/
diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx
index c9f983e17..01498dfcd 100644
--- a/src/output/plugins/httpd/HttpdInternal.hxx
+++ b/src/output/plugins/httpd/HttpdInternal.hxx
@@ -25,6 +25,7 @@
#ifndef MPD_OUTPUT_HTTPD_INTERNAL_H
#define MPD_OUTPUT_HTTPD_INTERNAL_H
+#include "HttpdClient.hxx"
#include "output/Internal.hxx"
#include "output/Timer.hxx"
#include "thread/Mutex.hxx"
@@ -33,12 +34,6 @@
#include "util/Cast.hxx"
#include "Compiler.h"
-#ifdef _LIBCPP_VERSION
-/* can't use incomplete template arguments with libc++ */
-#include "HttpdClient.hxx"
-#endif
-
-#include <forward_list>
#include <queue>
#include <list>
@@ -135,7 +130,8 @@ private:
* A linked list containing all clients which are currently
* connected.
*/
- std::forward_list<HttpdClient> clients;
+ boost::intrusive::list<HttpdClient,
+ boost::intrusive::constant_time_size<true>> clients;
/**
* A temporary buffer for the httpd_output_read_page()
@@ -147,7 +143,7 @@ private:
* The maximum and current number of clients connected
* at the same time.
*/
- unsigned clients_max, clients_cnt;
+ unsigned clients_max;
public:
HttpdOutput(EventLoop &_loop);
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
index d13f646f3..765a72d92 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
@@ -34,6 +34,7 @@
#include "event/Call.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
+#include "util/DeleteDisposer.hxx"
#include "Log.hxx"
#include <assert.h>
@@ -169,9 +170,9 @@ httpd_output_finish(AudioOutput *ao)
inline void
HttpdOutput::AddClient(int fd)
{
- clients.emplace_front(*this, fd, GetEventLoop(),
- encoder->plugin.tag == nullptr);
- ++clients_cnt;
+ auto *client = new HttpdClient(*this, fd, GetEventLoop(),
+ encoder->plugin.tag == nullptr);
+ clients.push_front(*client);
/* pass metadata to client */
if (metadata != nullptr)
@@ -235,7 +236,7 @@ HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid)
if (fd >= 0) {
/* can we allow additional client */
- if (open && (clients_max == 0 || clients_cnt < clients_max))
+ if (open && (clients_max == 0 || clients.size() < clients_max))
AddClient(fd);
else
close_socket(fd);
@@ -319,7 +320,6 @@ HttpdOutput::Open(AudioFormat &audio_format, Error &error)
/* initialize other attributes */
- clients_cnt = 0;
timer = new Timer(audio_format);
open = true;
@@ -347,7 +347,7 @@ HttpdOutput::Close()
delete timer;
BlockingCall(GetEventLoop(), [this](){
- clients.clear();
+ clients.clear_and_dispose(DeleteDisposer());
});
if (header != nullptr)
@@ -368,17 +368,10 @@ httpd_output_close(AudioOutput *ao)
void
HttpdOutput::RemoveClient(HttpdClient &client)
{
- assert(clients_cnt > 0);
+ assert(!clients.empty());
- for (auto prev = clients.before_begin(), i = std::next(prev);;
- prev = i, i = std::next(prev)) {
- assert(i != clients.end());
- if (&*i == &client) {
- clients.erase_after(prev);
- clients_cnt--;
- break;
- }
- }
+ clients.erase_and_dispose(clients.iterator_to(client),
+ DeleteDisposer());
}
void