Commit fa51db44 authored by Max Kellermann's avatar Max Kellermann

ServerSocket: replace callback with virtual method

parent cb9a05ac
...@@ -36,16 +36,20 @@ ...@@ -36,16 +36,20 @@
#define DEFAULT_PORT 6600 #define DEFAULT_PORT 6600
static ServerSocket *listen_socket; class ClientListener final : public ServerSocket {
int listen_port; public:
ClientListener():ServerSocket(*main_loop) {}
static void private:
listen_callback(int fd, const struct sockaddr *address, virtual void OnAccept(int fd, const sockaddr &address,
size_t address_length, int uid, G_GNUC_UNUSED void *ctx) size_t address_length, int uid) {
{
client_new(*main_loop, *global_partition, client_new(*main_loop, *global_partition,
fd, address, address_length, uid); fd, &address, address_length, uid);
} }
};
static ClientListener *listen_socket;
int listen_port;
static bool static bool
listen_add_config_param(unsigned int port, listen_add_config_param(unsigned int port,
...@@ -98,7 +102,7 @@ listen_global_init(GError **error_r) ...@@ -98,7 +102,7 @@ listen_global_init(GError **error_r)
bool success; bool success;
GError *error = NULL; GError *error = NULL;
listen_socket = new ServerSocket(*main_loop, listen_callback, nullptr); listen_socket = new ClientListener();
if (listen_systemd_activation(&error)) if (listen_systemd_activation(&error))
return true; return true;
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#define DEFAULT_PORT 6600 #define DEFAULT_PORT 6600
class OneServerSocket final : private SocketMonitor { class OneServerSocket final : private SocketMonitor {
const ServerSocket &parent; ServerSocket &parent;
const unsigned serial; const unsigned serial;
...@@ -64,7 +64,7 @@ class OneServerSocket final : private SocketMonitor { ...@@ -64,7 +64,7 @@ class OneServerSocket final : private SocketMonitor {
struct sockaddr *address; struct sockaddr *address;
public: public:
OneServerSocket(EventLoop &_loop, const ServerSocket &_parent, OneServerSocket(EventLoop &_loop, ServerSocket &_parent,
unsigned _serial, unsigned _serial,
const struct sockaddr *_address, const struct sockaddr *_address,
size_t _address_length) size_t _address_length)
...@@ -176,10 +176,9 @@ OneServerSocket::Accept() ...@@ -176,10 +176,9 @@ OneServerSocket::Accept()
(const char *)msg); (const char *)msg);
} }
parent.callback(peer_fd, parent.OnAccept(peer_fd,
(const struct sockaddr*)&peer_address, (const sockaddr &)peer_address,
peer_address_length, get_remote_uid(peer_fd), peer_address_length, get_remote_uid(peer_fd));
parent.callback_ctx);
} }
bool bool
...@@ -213,12 +212,8 @@ OneServerSocket::Open(GError **error_r) ...@@ -213,12 +212,8 @@ OneServerSocket::Open(GError **error_r)
return true; return true;
} }
ServerSocket::ServerSocket(EventLoop &_loop, ServerSocket::ServerSocket(EventLoop &_loop)
server_socket_callback_t _callback, :loop(_loop), next_serial(1) {}
void *_callback_ctx)
:loop(_loop),
callback(_callback), callback_ctx(_callback_ctx),
next_serial(1) {}
/* this is just here to allow the OneServerSocket forward /* this is just here to allow the OneServerSocket forward
declaration */ declaration */
......
...@@ -41,16 +41,12 @@ class ServerSocket { ...@@ -41,16 +41,12 @@ class ServerSocket {
EventLoop &loop; EventLoop &loop;
server_socket_callback_t callback;
void *callback_ctx;
std::forward_list<OneServerSocket> sockets; std::forward_list<OneServerSocket> sockets;
unsigned next_serial; unsigned next_serial;
public: public:
ServerSocket(EventLoop &_loop, ServerSocket(EventLoop &_loop);
server_socket_callback_t _callback, void *_callback_ctx);
~ServerSocket(); ~ServerSocket();
private: private:
...@@ -112,6 +108,10 @@ public: ...@@ -112,6 +108,10 @@ public:
bool Open(GError **error_r); bool Open(GError **error_r);
void Close(); void Close();
protected:
virtual void OnAccept(int fd, const sockaddr &address,
size_t address_length, int uid) = 0;
}; };
#endif #endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "output_internal.h" #include "output_internal.h"
#include "timer.h" #include "timer.h"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "event/ServerSocket.hxx"
#include <glib.h> #include <glib.h>
...@@ -39,7 +40,7 @@ class ServerSocket; ...@@ -39,7 +40,7 @@ class ServerSocket;
class HttpdClient; class HttpdClient;
class Page; class Page;
struct HttpdOutput { struct HttpdOutput final : private ServerSocket {
struct audio_output base; struct audio_output base;
/** /**
...@@ -79,11 +80,6 @@ struct HttpdOutput { ...@@ -79,11 +80,6 @@ struct HttpdOutput {
struct timer *timer; struct timer *timer;
/** /**
* The listener socket.
*/
ServerSocket *server_socket;
/**
* The header page, which is sent to every client on connect. * The header page, which is sent to every client on connect.
*/ */
Page *header; Page *header;
...@@ -201,6 +197,10 @@ struct HttpdOutput { ...@@ -201,6 +197,10 @@ struct HttpdOutput {
bool EncodeAndPlay(const void *chunk, size_t size, GError **error_r); bool EncodeAndPlay(const void *chunk, size_t size, GError **error_r);
void SendTag(const struct tag *tag); void SendTag(const struct tag *tag);
private:
virtual void OnAccept(int fd, const sockaddr &address,
size_t address_length, int uid) override;
}; };
#endif #endif
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "Page.hxx" #include "Page.hxx"
#include "IcyMetaDataServer.hxx" #include "IcyMetaDataServer.hxx"
#include "fd_util.h" #include "fd_util.h"
#include "event/ServerSocket.hxx"
#include "Main.hxx" #include "Main.hxx"
#include <assert.h> #include <assert.h>
...@@ -54,14 +53,10 @@ httpd_output_quark(void) ...@@ -54,14 +53,10 @@ httpd_output_quark(void)
return g_quark_from_static_string("httpd_output"); 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 inline
HttpdOutput::HttpdOutput(EventLoop &_loop) HttpdOutput::HttpdOutput(EventLoop &_loop)
:encoder(nullptr), unflushed_input(0), :ServerSocket(_loop),
server_socket(new ServerSocket(_loop, httpd_listen_in_event, this)), encoder(nullptr), unflushed_input(0),
metadata(nullptr) metadata(nullptr)
{ {
} }
...@@ -74,8 +69,6 @@ HttpdOutput::~HttpdOutput() ...@@ -74,8 +69,6 @@ HttpdOutput::~HttpdOutput()
if (encoder != nullptr) if (encoder != nullptr)
encoder_finish(encoder); encoder_finish(encoder);
delete server_socket;
} }
inline bool inline bool
...@@ -84,7 +77,7 @@ HttpdOutput::Bind(GError **error_r) ...@@ -84,7 +77,7 @@ HttpdOutput::Bind(GError **error_r)
open = false; open = false;
const ScopeLock protect(mutex); const ScopeLock protect(mutex);
return server_socket->Open(error_r); return ServerSocket::Open(error_r);
} }
inline void inline void
...@@ -93,7 +86,7 @@ HttpdOutput::Unbind() ...@@ -93,7 +86,7 @@ HttpdOutput::Unbind()
assert(!open); assert(!open);
const ScopeLock protect(mutex); const ScopeLock protect(mutex);
server_socket->Close(); ServerSocket::Close();
} }
inline bool inline bool
...@@ -125,8 +118,8 @@ HttpdOutput::Configure(const config_param *param, GError **error_r) ...@@ -125,8 +118,8 @@ HttpdOutput::Configure(const config_param *param, GError **error_r)
config_get_block_string(param, "bind_to_address", NULL); config_get_block_string(param, "bind_to_address", NULL);
bool success = bind_to_address != NULL && bool success = bind_to_address != NULL &&
strcmp(bind_to_address, "any") != 0 strcmp(bind_to_address, "any") != 0
? server_socket->AddHost(bind_to_address, port, error_r) ? AddHost(bind_to_address, port, error_r)
: server_socket->AddPort(port, error_r); : AddPort(port, error_r);
if (!success) if (!success)
return false; return false;
...@@ -165,12 +158,21 @@ httpd_output_init(const struct config_param *param, ...@@ -165,12 +158,21 @@ httpd_output_init(const struct config_param *param,
return &httpd->base; 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 * static inline constexpr HttpdOutput *
Cast(audio_output *ao) Cast(audio_output *ao)
{ {
return (HttpdOutput *)((char *)ao - offsetof(HttpdOutput, base)); return (HttpdOutput *)((char *)ao - offsetof(HttpdOutput, base));
} }
#if GCC_CHECK_VERSION(4,6) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
static void static void
httpd_output_finish(struct audio_output *ao) httpd_output_finish(struct audio_output *ao)
{ {
...@@ -196,18 +198,16 @@ HttpdOutput::AddClient(int fd) ...@@ -196,18 +198,16 @@ HttpdOutput::AddClient(int fd)
clients.front().PushMetaData(metadata); clients.front().PushMetaData(metadata);
} }
static void void
httpd_listen_in_event(int fd, const struct sockaddr *address, HttpdOutput::OnAccept(int fd, const sockaddr &address,
size_t address_length, G_GNUC_UNUSED int uid, void *ctx) size_t address_length, gcc_unused int uid)
{ {
HttpdOutput *httpd = (HttpdOutput *)ctx;
/* the listener socket has become readable - a client has /* the listener socket has become readable - a client has
connected */ connected */
#ifdef HAVE_LIBWRAP #ifdef HAVE_LIBWRAP
if (address->sa_family != AF_UNIX) { if (address.sa_family != AF_UNIX) {
char *hostaddr = sockaddr_to_string(address, address_length, NULL); char *hostaddr = sockaddr_to_string(&address, address_length, NULL);
const char *progname = g_get_prgname(); const char *progname = g_get_prgname();
struct request_info req; struct request_info req;
...@@ -231,14 +231,12 @@ httpd_listen_in_event(int fd, const struct sockaddr *address, ...@@ -231,14 +231,12 @@ httpd_listen_in_event(int fd, const struct sockaddr *address,
(void)address_length; (void)address_length;
#endif /* HAVE_WRAP */ #endif /* HAVE_WRAP */
const ScopeLock protect(httpd->mutex); const ScopeLock protect(mutex);
if (fd >= 0) { if (fd >= 0) {
/* can we allow additional client */ /* can we allow additional client */
if (httpd->open && if (open && (clients_max == 0 || clients_cnt < clients_max))
(httpd->clients_max == 0 || AddClient(fd);
httpd->clients_cnt < httpd->clients_max))
httpd->AddClient(fd);
else else
close_socket(fd); close_socket(fd);
} else if (fd < 0 && errno != EINTR) { } else if (fd < 0 && errno != EINTR) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment