output/httpd: use boost::intrusive::list instead of std::forward_list

This commit is contained in:
Max Kellermann 2015-10-19 15:18:47 +02:00
parent 8d23706354
commit 6bea346c41
3 changed files with 18 additions and 25 deletions

View File

@ -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.
*/

View File

@ -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);

View File

@ -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(),
auto *client = new HttpdClient(*this, fd, GetEventLoop(),
encoder->plugin.tag == nullptr);
++clients_cnt;
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