aboutsummaryrefslogtreecommitdiffstats
path: root/src/output/HttpdInternal.hxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/output/HttpdInternal.hxx68
1 files changed, 67 insertions, 1 deletions
diff --git a/src/output/HttpdInternal.hxx b/src/output/HttpdInternal.hxx
index b76493a44..8d35d35e9 100644
--- a/src/output/HttpdInternal.hxx
+++ b/src/output/HttpdInternal.hxx
@@ -29,6 +29,8 @@
#include "Timer.hxx"
#include "thread/Mutex.hxx"
#include "event/ServerSocket.hxx"
+#include "event/DeferredMonitor.hxx"
+#include "util/Cast.hxx"
#ifdef _LIBCPP_VERSION
/* can't use incomplete template arguments with libc++ */
@@ -36,6 +38,8 @@
#endif
#include <forward_list>
+#include <queue>
+#include <list>
struct config_param;
class Error;
@@ -46,7 +50,7 @@ class Page;
struct Encoder;
struct Tag;
-struct HttpdOutput final : private ServerSocket {
+class HttpdOutput final : ServerSocket, DeferredMonitor {
struct audio_output base;
/**
@@ -68,6 +72,7 @@ struct HttpdOutput final : private ServerSocket {
*/
size_t unflushed_input;
+public:
/**
* The MIME type produced by the #encoder.
*/
@@ -80,6 +85,13 @@ struct HttpdOutput final : private ServerSocket {
mutable Mutex mutex;
/**
+ * This condition gets signalled when an item is removed from
+ * #pages.
+ */
+ Cond cond;
+
+private:
+ /**
* A #Timer object to synchronize this output with the
* wallclock.
*/
@@ -96,6 +108,15 @@ struct HttpdOutput final : private ServerSocket {
Page *metadata;
/**
+ * The page queue, i.e. pages from the encoder to be
+ * broadcasted to all clients. This container is necessary to
+ * pass pages from the OutputThread to the IOThread. It is
+ * protected by #mutex, and removing signals #cond.
+ */
+ std::queue<Page *, std::list<Page *>> pages;
+
+ public:
+ /**
* The configured name.
*/
char const *name;
@@ -108,6 +129,7 @@ struct HttpdOutput final : private ServerSocket {
*/
char const *website;
+private:
/**
* A linked list containing all clients which are currently
* connected.
@@ -126,11 +148,46 @@ struct HttpdOutput final : private ServerSocket {
*/
unsigned clients_max, clients_cnt;
+public:
HttpdOutput(EventLoop &_loop);
~HttpdOutput();
+#if GCC_CHECK_VERSION(4,6) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+#endif
+
+ static constexpr HttpdOutput *Cast(audio_output *ao) {
+ return ContainerCast(ao, HttpdOutput, base);
+ }
+
+#if GCC_CHECK_VERSION(4,6) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+ using DeferredMonitor::GetEventLoop;
+
+ bool Init(const config_param &param, Error &error);
+
+ void Finish() {
+ ao_base_finish(&base);
+ }
+
bool Configure(const config_param &param, Error &error);
+ audio_output *InitAndConfigure(const config_param &param,
+ Error &error) {
+ if (!Init(param, error))
+ return nullptr;
+
+ if (!Configure(param, error)) {
+ Finish();
+ return nullptr;
+ }
+
+ return &base;
+ }
+
bool Bind(Error &error);
void Unbind();
@@ -181,6 +238,9 @@ struct HttpdOutput final : private ServerSocket {
*/
void SendHeader(HttpdClient &client) const;
+ gcc_pure
+ unsigned Delay() const;
+
/**
* Reads data from the encoder (as much as available) and
* returns it as a new #page object.
@@ -203,7 +263,13 @@ struct HttpdOutput final : private ServerSocket {
void SendTag(const Tag *tag);
+ size_t Play(const void *chunk, size_t size, Error &error);
+
+ void CancelAllClients();
+
private:
+ virtual void RunDeferred() override;
+
virtual void OnAccept(int fd, const sockaddr &address,
size_t address_length, int uid) override;
};