ServerSocket: replace callback with virtual method
This commit is contained in:
parent
cb9a05ac77
commit
fa51db449f
@ -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) {}
|
||||
|
||||
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);
|
||||
}
|
||||
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 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;
|
||||
|
||||
/**
|
||||
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user