Commit fa51db44 authored by Max Kellermann's avatar Max Kellermann

ServerSocket: replace callback with virtual method

parent cb9a05ac
......@@ -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;
......
......@@ -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 */
......
......@@ -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
......@@ -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
......@@ -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) {
......
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