From fa51db449fdb9558a4cb4542a86437ac9dd3ddbd Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Jan 2013 13:20:27 +0100 Subject: ServerSocket: replace callback with virtual method --- src/Listen.cxx | 24 +++++++++++--------- src/event/ServerSocket.cxx | 19 ++++++---------- src/event/ServerSocket.hxx | 10 ++++----- src/output/HttpdInternal.hxx | 12 +++++----- src/output/HttpdOutputPlugin.cxx | 48 +++++++++++++++++++--------------------- 5 files changed, 55 insertions(+), 58 deletions(-) (limited to 'src') 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 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 @@ -39,7 +40,7 @@ class ServerSocket; class HttpdClient; class Page; -struct HttpdOutput { +struct HttpdOutput final : private ServerSocket { struct audio_output base; /** @@ -78,11 +79,6 @@ struct HttpdOutput { */ struct timer *timer; - /** - * The listener socket. - */ - ServerSocket *server_socket; - /** * The header page, which is sent to every client on connect. */ @@ -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 @@ -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) { -- cgit v1.2.3