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 "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. | ||||
| 	 */ | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann