aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Listen.cxx24
-rw-r--r--src/event/ServerSocket.cxx19
-rw-r--r--src/event/ServerSocket.hxx10
-rw-r--r--src/output/HttpdInternal.hxx12
-rw-r--r--src/output/HttpdOutputPlugin.cxx48
5 files changed, 55 insertions, 58 deletions
diff --git a/src/Listen.cxx b/src/Listen.cxx
index e56a0ead2..26c9e100d 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -36,16 +36,20 @@
#define DEFAULT_PORT 6600
-static ServerSocket *listen_socket;
-int listen_port;
+class ClientListener final : public ServerSocket {
+public:
+ ClientListener():ServerSocket(*main_loop) {}
+
+private:
+ virtual void OnAccept(int fd, const sockaddr &address,
+ size_t address_length, int uid) {
+ client_new(*main_loop, *global_partition,
+ fd, &address, address_length, uid);
+ }
+};
-static void
-listen_callback(int fd, const struct sockaddr *address,
- size_t address_length, int uid, G_GNUC_UNUSED void *ctx)
-{
- client_new(*main_loop, *global_partition,
- fd, address, address_length, uid);
-}
+static ClientListener *listen_socket;
+int listen_port;
static bool
listen_add_config_param(unsigned int port,
@@ -98,7 +102,7 @@ listen_global_init(GError **error_r)
bool success;
GError *error = NULL;
- listen_socket = new ServerSocket(*main_loop, listen_callback, nullptr);
+ listen_socket = new ClientListener();
if (listen_systemd_activation(&error))
return true;
diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx
index ea2f07e38..d444933a0 100644
--- a/src/event/ServerSocket.cxx
+++ b/src/event/ServerSocket.cxx
@@ -54,7 +54,7 @@
#define DEFAULT_PORT 6600
class OneServerSocket final : private SocketMonitor {
- const ServerSocket &parent;
+ ServerSocket &parent;
const unsigned serial;
@@ -64,7 +64,7 @@ class OneServerSocket final : private SocketMonitor {
struct sockaddr *address;
public:
- OneServerSocket(EventLoop &_loop, const ServerSocket &_parent,
+ OneServerSocket(EventLoop &_loop, ServerSocket &_parent,
unsigned _serial,
const struct sockaddr *_address,
size_t _address_length)
@@ -176,10 +176,9 @@ OneServerSocket::Accept()
(const char *)msg);
}
- parent.callback(peer_fd,
- (const struct sockaddr*)&peer_address,
- peer_address_length, get_remote_uid(peer_fd),
- parent.callback_ctx);
+ parent.OnAccept(peer_fd,
+ (const sockaddr &)peer_address,
+ peer_address_length, get_remote_uid(peer_fd));
}
bool
@@ -213,12 +212,8 @@ OneServerSocket::Open(GError **error_r)
return true;
}
-ServerSocket::ServerSocket(EventLoop &_loop,
- server_socket_callback_t _callback,
- void *_callback_ctx)
- :loop(_loop),
- callback(_callback), callback_ctx(_callback_ctx),
- next_serial(1) {}
+ServerSocket::ServerSocket(EventLoop &_loop)
+ :loop(_loop), next_serial(1) {}
/* this is just here to allow the OneServerSocket forward
declaration */
diff --git a/src/event/ServerSocket.hxx b/src/event/ServerSocket.hxx
index bfa4d3f3b..ec922d97f 100644
--- a/src/event/ServerSocket.hxx
+++ b/src/event/ServerSocket.hxx
@@ -41,16 +41,12 @@ class ServerSocket {
EventLoop &loop;
- server_socket_callback_t callback;
- void *callback_ctx;
-
std::forward_list<OneServerSocket> sockets;
unsigned next_serial;
public:
- ServerSocket(EventLoop &_loop,
- server_socket_callback_t _callback, void *_callback_ctx);
+ ServerSocket(EventLoop &_loop);
~ServerSocket();
private:
@@ -112,6 +108,10 @@ public:
bool Open(GError **error_r);
void Close();
+
+protected:
+ virtual void OnAccept(int fd, const sockaddr &address,
+ size_t address_length, int uid) = 0;
};
#endif
diff --git a/src/output/HttpdInternal.hxx b/src/output/HttpdInternal.hxx
index 4e6eb4f58..f1ee513ed 100644
--- a/src/output/HttpdInternal.hxx
+++ b/src/output/HttpdInternal.hxx
@@ -28,6 +28,7 @@
#include "output_internal.h"
#include "timer.h"
#include "thread/Mutex.hxx"
+#include "event/ServerSocket.hxx"
#include <glib.h>
@@ -39,7 +40,7 @@ class ServerSocket;
class HttpdClient;
class Page;
-struct HttpdOutput {
+struct HttpdOutput final : private ServerSocket {
struct audio_output base;
/**
@@ -79,11 +80,6 @@ struct HttpdOutput {
struct timer *timer;
/**
- * The listener socket.
- */
- ServerSocket *server_socket;
-
- /**
* The header page, which is sent to every client on connect.
*/
Page *header;
@@ -201,6 +197,10 @@ struct HttpdOutput {
bool EncodeAndPlay(const void *chunk, size_t size, GError **error_r);
void SendTag(const struct tag *tag);
+
+private:
+ virtual void OnAccept(int fd, const sockaddr &address,
+ size_t address_length, int uid) override;
};
#endif
diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx
index a4714637a..6c67030cb 100644
--- a/src/output/HttpdOutputPlugin.cxx
+++ b/src/output/HttpdOutputPlugin.cxx
@@ -28,7 +28,6 @@
#include "Page.hxx"
#include "IcyMetaDataServer.hxx"
#include "fd_util.h"
-#include "event/ServerSocket.hxx"
#include "Main.hxx"
#include <assert.h>
@@ -54,14 +53,10 @@ httpd_output_quark(void)
return g_quark_from_static_string("httpd_output");
}
-static void
-httpd_listen_in_event(int fd, const struct sockaddr *address,
- size_t address_length, int uid, void *ctx);
-
inline
HttpdOutput::HttpdOutput(EventLoop &_loop)
- :encoder(nullptr), unflushed_input(0),
- server_socket(new ServerSocket(_loop, httpd_listen_in_event, this)),
+ :ServerSocket(_loop),
+ encoder(nullptr), unflushed_input(0),
metadata(nullptr)
{
}
@@ -74,8 +69,6 @@ HttpdOutput::~HttpdOutput()
if (encoder != nullptr)
encoder_finish(encoder);
- delete server_socket;
-
}
inline bool
@@ -84,7 +77,7 @@ HttpdOutput::Bind(GError **error_r)
open = false;
const ScopeLock protect(mutex);
- return server_socket->Open(error_r);
+ return ServerSocket::Open(error_r);
}
inline void
@@ -93,7 +86,7 @@ HttpdOutput::Unbind()
assert(!open);
const ScopeLock protect(mutex);
- server_socket->Close();
+ ServerSocket::Close();
}
inline bool
@@ -125,8 +118,8 @@ HttpdOutput::Configure(const config_param *param, GError **error_r)
config_get_block_string(param, "bind_to_address", NULL);
bool success = bind_to_address != NULL &&
strcmp(bind_to_address, "any") != 0
- ? server_socket->AddHost(bind_to_address, port, error_r)
- : server_socket->AddPort(port, error_r);
+ ? AddHost(bind_to_address, port, error_r)
+ : AddPort(port, error_r);
if (!success)
return false;
@@ -165,12 +158,21 @@ httpd_output_init(const struct config_param *param,
return &httpd->base;
}
+#if GCC_CHECK_VERSION(4,6) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+#endif
+
static inline constexpr HttpdOutput *
Cast(audio_output *ao)
{
return (HttpdOutput *)((char *)ao - offsetof(HttpdOutput, base));
}
+#if GCC_CHECK_VERSION(4,6) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
static void
httpd_output_finish(struct audio_output *ao)
{
@@ -196,18 +198,16 @@ HttpdOutput::AddClient(int fd)
clients.front().PushMetaData(metadata);
}
-static void
-httpd_listen_in_event(int fd, const struct sockaddr *address,
- size_t address_length, G_GNUC_UNUSED int uid, void *ctx)
+void
+HttpdOutput::OnAccept(int fd, const sockaddr &address,
+ size_t address_length, gcc_unused int uid)
{
- HttpdOutput *httpd = (HttpdOutput *)ctx;
-
/* the listener socket has become readable - a client has
connected */
#ifdef HAVE_LIBWRAP
- if (address->sa_family != AF_UNIX) {
- char *hostaddr = sockaddr_to_string(address, address_length, NULL);
+ if (address.sa_family != AF_UNIX) {
+ char *hostaddr = sockaddr_to_string(&address, address_length, NULL);
const char *progname = g_get_prgname();
struct request_info req;
@@ -231,14 +231,12 @@ httpd_listen_in_event(int fd, const struct sockaddr *address,
(void)address_length;
#endif /* HAVE_WRAP */
- const ScopeLock protect(httpd->mutex);
+ const ScopeLock protect(mutex);
if (fd >= 0) {
/* can we allow additional client */
- if (httpd->open &&
- (httpd->clients_max == 0 ||
- httpd->clients_cnt < httpd->clients_max))
- httpd->AddClient(fd);
+ if (open && (clients_max == 0 || clients_cnt < clients_max))
+ AddClient(fd);
else
close_socket(fd);
} else if (fd < 0 && errno != EINTR) {