diff options
Diffstat (limited to 'src/output/plugins/httpd')
-rw-r--r-- | src/output/plugins/httpd/HttpdClient.hxx | 6 | ||||
-rw-r--r-- | src/output/plugins/httpd/HttpdInternal.hxx | 12 | ||||
-rw-r--r-- | src/output/plugins/httpd/HttpdOutputPlugin.cxx | 25 |
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 |