output/httpd: use boost::intrusive::list instead of std::forward_list
This commit is contained in:
		| @@ -23,6 +23,8 @@ | |||||||
| #include "event/BufferedSocket.hxx" | #include "event/BufferedSocket.hxx" | ||||||
| #include "Compiler.h" | #include "Compiler.h" | ||||||
|  |  | ||||||
|  | #include <boost/intrusive/list.hpp> | ||||||
|  |  | ||||||
| #include <queue> | #include <queue> | ||||||
| #include <list> | #include <list> | ||||||
|  |  | ||||||
| @@ -31,7 +33,9 @@ | |||||||
| class HttpdOutput; | class HttpdOutput; | ||||||
| class Page; | 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. | 	 * The httpd output object this client is connected to. | ||||||
| 	 */ | 	 */ | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
| #ifndef MPD_OUTPUT_HTTPD_INTERNAL_H | #ifndef MPD_OUTPUT_HTTPD_INTERNAL_H | ||||||
| #define MPD_OUTPUT_HTTPD_INTERNAL_H | #define MPD_OUTPUT_HTTPD_INTERNAL_H | ||||||
|  |  | ||||||
|  | #include "HttpdClient.hxx" | ||||||
| #include "output/Internal.hxx" | #include "output/Internal.hxx" | ||||||
| #include "output/Timer.hxx" | #include "output/Timer.hxx" | ||||||
| #include "thread/Mutex.hxx" | #include "thread/Mutex.hxx" | ||||||
| @@ -33,12 +34,6 @@ | |||||||
| #include "util/Cast.hxx" | #include "util/Cast.hxx" | ||||||
| #include "Compiler.h" | #include "Compiler.h" | ||||||
|  |  | ||||||
| #ifdef _LIBCPP_VERSION |  | ||||||
| /* can't use incomplete template arguments with libc++ */ |  | ||||||
| #include "HttpdClient.hxx" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <forward_list> |  | ||||||
| #include <queue> | #include <queue> | ||||||
| #include <list> | #include <list> | ||||||
|  |  | ||||||
| @@ -135,7 +130,8 @@ private: | |||||||
| 	 * A linked list containing all clients which are currently | 	 * A linked list containing all clients which are currently | ||||||
| 	 * connected. | 	 * 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() | 	 * A temporary buffer for the httpd_output_read_page() | ||||||
| @@ -147,7 +143,7 @@ private: | |||||||
| 	 * The maximum and current number of clients connected | 	 * The maximum and current number of clients connected | ||||||
| 	 * at the same time. | 	 * at the same time. | ||||||
| 	 */ | 	 */ | ||||||
| 	unsigned clients_max, clients_cnt; | 	unsigned clients_max; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	HttpdOutput(EventLoop &_loop); | 	HttpdOutput(EventLoop &_loop); | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ | |||||||
| #include "event/Call.hxx" | #include "event/Call.hxx" | ||||||
| #include "util/Error.hxx" | #include "util/Error.hxx" | ||||||
| #include "util/Domain.hxx" | #include "util/Domain.hxx" | ||||||
|  | #include "util/DeleteDisposer.hxx" | ||||||
| #include "Log.hxx" | #include "Log.hxx" | ||||||
|  |  | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| @@ -169,9 +170,9 @@ httpd_output_finish(AudioOutput *ao) | |||||||
| inline void | inline void | ||||||
| HttpdOutput::AddClient(int fd) | HttpdOutput::AddClient(int fd) | ||||||
| { | { | ||||||
| 	clients.emplace_front(*this, fd, GetEventLoop(), | 	auto *client = new HttpdClient(*this, fd, GetEventLoop(), | ||||||
| 				       encoder->plugin.tag == nullptr); | 				       encoder->plugin.tag == nullptr); | ||||||
| 	++clients_cnt; | 	clients.push_front(*client); | ||||||
|  |  | ||||||
| 	/* pass metadata to client */ | 	/* pass metadata to client */ | ||||||
| 	if (metadata != nullptr) | 	if (metadata != nullptr) | ||||||
| @@ -235,7 +236,7 @@ HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid) | |||||||
|  |  | ||||||
| 	if (fd >= 0) { | 	if (fd >= 0) { | ||||||
| 		/* can we allow additional client */ | 		/* 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); | 			AddClient(fd); | ||||||
| 		else | 		else | ||||||
| 			close_socket(fd); | 			close_socket(fd); | ||||||
| @@ -319,7 +320,6 @@ HttpdOutput::Open(AudioFormat &audio_format, Error &error) | |||||||
|  |  | ||||||
| 	/* initialize other attributes */ | 	/* initialize other attributes */ | ||||||
|  |  | ||||||
| 	clients_cnt = 0; |  | ||||||
| 	timer = new Timer(audio_format); | 	timer = new Timer(audio_format); | ||||||
|  |  | ||||||
| 	open = true; | 	open = true; | ||||||
| @@ -347,7 +347,7 @@ HttpdOutput::Close() | |||||||
| 	delete timer; | 	delete timer; | ||||||
|  |  | ||||||
| 	BlockingCall(GetEventLoop(), [this](){ | 	BlockingCall(GetEventLoop(), [this](){ | ||||||
| 			clients.clear(); | 			clients.clear_and_dispose(DeleteDisposer()); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 	if (header != nullptr) | 	if (header != nullptr) | ||||||
| @@ -368,17 +368,10 @@ httpd_output_close(AudioOutput *ao) | |||||||
| void | void | ||||||
| HttpdOutput::RemoveClient(HttpdClient &client) | HttpdOutput::RemoveClient(HttpdClient &client) | ||||||
| { | { | ||||||
| 	assert(clients_cnt > 0); | 	assert(!clients.empty()); | ||||||
|  |  | ||||||
| 	for (auto prev = clients.before_begin(), i = std::next(prev);; | 	clients.erase_and_dispose(clients.iterator_to(client), | ||||||
| 	     prev = i, i = std::next(prev)) { | 				  DeleteDisposer()); | ||||||
| 		assert(i != clients.end()); |  | ||||||
| 		if (&*i == &client) { |  | ||||||
| 			clients.erase_after(prev); |  | ||||||
| 			clients_cnt--; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann