ServerSocket: replace callback with virtual method
This commit is contained in:
parent
cb9a05ac77
commit
fa51db449f
@ -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)
|
|||||||
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 @@
|
|||||||
#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 {
|
|||||||
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()
|
|||||||
(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)
|
|||||||
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 {
|
|||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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;
|
|||||||
class HttpdClient;
|
class HttpdClient;
|
||||||
class Page;
|
class Page;
|
||||||
|
|
||||||
struct HttpdOutput {
|
struct HttpdOutput final : private ServerSocket {
|
||||||
struct audio_output base;
|
struct audio_output base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,11 +79,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.
|
||||||
*/
|
*/
|
||||||
@ -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 @@
|
|||||||
#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)
|
|||||||
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()
|
|||||||
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)
|
|||||||
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()
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
(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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user