ServerSocket: use the SocketMonitor class

This commit is contained in:
Max Kellermann 2013-01-15 22:50:49 +01:00
parent a0ebd444ad
commit 0dd5f2915a
5 changed files with 40 additions and 56 deletions

View File

@ -92,13 +92,15 @@ listen_systemd_activation(GError **error_r)
bool
listen_global_init(GError **error_r)
{
assert(main_loop != nullptr);
int port = config_get_positive(CONF_PORT, DEFAULT_PORT);
const struct config_param *param =
config_get_next_param(CONF_BIND_TO_ADDRESS, NULL);
bool success;
GError *error = NULL;
listen_socket = server_socket_new(listen_callback, NULL);
listen_socket = server_socket_new(*main_loop, listen_callback, NULL);
if (listen_systemd_activation(&error))
return true;

View File

@ -398,6 +398,9 @@ int mpd_main(int argc, char *argv[])
return EXIT_FAILURE;
}
main_task = g_thread_self();
main_loop = new EventLoop(EventLoop::Default());
success = listen_global_init(&error);
if (!success) {
g_warning("%s", error->message);
@ -407,9 +410,6 @@ int mpd_main(int argc, char *argv[])
daemonize_set_user();
main_task = g_thread_self();
main_loop = new EventLoop(EventLoop::Default());
GlobalEvents::Initialize();
GlobalEvents::Register(GlobalEvents::IDLE, idle_event_emitted);
GlobalEvents::Register(GlobalEvents::SHUTDOWN, shutdown_event_emitted);

View File

@ -26,9 +26,9 @@
#include "ServerSocket.hxx"
#include "SocketUtil.hxx"
#include "SocketError.hxx"
#include "event/SocketMonitor.hxx"
#include "resolver.h"
#include "fd_util.h"
#include "glib_socket.h"
#include <forward_list>
@ -55,24 +55,22 @@
#define DEFAULT_PORT 6600
struct OneServerSocket {
struct OneServerSocket final : private SocketMonitor {
const server_socket &parent;
const unsigned serial;
int fd;
guint source_id;
char *path;
size_t address_length;
struct sockaddr *address;
OneServerSocket(const server_socket &_parent, unsigned _serial,
OneServerSocket(EventLoop &_loop, const server_socket &_parent,
unsigned _serial,
const struct sockaddr *_address,
size_t _address_length)
:parent(_parent), serial(_serial),
fd(-1),
:SocketMonitor(_loop),
parent(_parent), serial(_serial),
path(nullptr),
address_length(_address_length),
address((sockaddr *)g_memdup(_address, _address_length))
@ -85,23 +83,30 @@ struct OneServerSocket {
OneServerSocket &operator=(const OneServerSocket &other) = delete;
~OneServerSocket() {
Close();
g_free(path);
g_free(address);
}
bool Open(GError **error_r);
void Close();
using SocketMonitor::Close;
char *ToString() const;
void SetFD(int fd);
void SetFD(int _fd) {
SocketMonitor::Open(_fd);
SocketMonitor::ScheduleRead();
}
void Accept();
private:
virtual void OnSocketReady(unsigned flags) override;
};
struct server_socket {
EventLoop &loop;
server_socket_callback_t callback;
void *callback_ctx;
@ -109,8 +114,10 @@ struct server_socket {
unsigned next_serial;
server_socket(server_socket_callback_t _callback, void *_callback_ctx)
:callback(_callback), callback_ctx(_callback_ctx),
server_socket(EventLoop &_loop,
server_socket_callback_t _callback, void *_callback_ctx)
:loop(_loop),
callback(_callback), callback_ctx(_callback_ctx),
next_serial(1) {}
void Close();
@ -123,9 +130,10 @@ server_socket_quark(void)
}
struct server_socket *
server_socket_new(server_socket_callback_t callback, void *callback_ctx)
server_socket_new(EventLoop &loop,
server_socket_callback_t callback, void *callback_ctx)
{
return new server_socket(callback, callback_ctx);
return new server_socket(loop, callback, callback_ctx);
}
void
@ -177,7 +185,7 @@ OneServerSocket::Accept()
struct sockaddr_storage peer_address;
size_t peer_address_length = sizeof(peer_address);
int peer_fd =
accept_cloexec_nonblock(fd, (struct sockaddr*)&peer_address,
accept_cloexec_nonblock(Get(), (struct sockaddr*)&peer_address,
&peer_address_length);
if (peer_fd < 0) {
const SocketErrorMessage msg;
@ -197,35 +205,16 @@ OneServerSocket::Accept()
parent.callback_ctx);
}
static gboolean
server_socket_in_event(G_GNUC_UNUSED GIOChannel *source,
G_GNUC_UNUSED GIOCondition condition,
gpointer data)
{
OneServerSocket &s = *(OneServerSocket *)data;
s.Accept();
return true;
}
void
OneServerSocket::SetFD(int _fd)
OneServerSocket::OnSocketReady(gcc_unused unsigned flags)
{
assert(fd < 0);
assert(_fd >= 0);
fd = _fd;
GIOChannel *channel = g_io_channel_new_socket(fd);
source_id = g_io_add_watch(channel, G_IO_IN,
server_socket_in_event, this);
g_io_channel_unref(channel);
Accept();
}
inline bool
OneServerSocket::Open(GError **error_r)
{
assert(fd < 0);
assert(!IsDefined());
int _fd = socket_bind_listen(address->sa_family,
SOCK_STREAM, 0,
@ -309,17 +298,6 @@ server_socket_open(struct server_socket *ss, GError **error_r)
return true;
}
void
OneServerSocket::Close()
{
if (fd < 0)
return;
g_source_remove(source_id);
close_socket(fd);
fd = -1;
}
void
server_socket::Close()
{
@ -340,7 +318,7 @@ server_socket_add_address(struct server_socket *ss,
{
assert(ss != nullptr);
ss->sockets.emplace_front(*ss, ss->next_serial,
ss->sockets.emplace_front(ss->loop, *ss, ss->next_serial,
address, address_length);
return ss->sockets.front();

View File

@ -25,6 +25,7 @@
#include <stddef.h>
struct sockaddr;
class EventLoop;
typedef void (*server_socket_callback_t)(int fd,
const struct sockaddr *address,
@ -32,7 +33,8 @@ typedef void (*server_socket_callback_t)(int fd,
void *ctx);
struct server_socket *
server_socket_new(server_socket_callback_t callback, void *callback_ctx);
server_socket_new(EventLoop &loop,
server_socket_callback_t callback, void *callback_ctx);
void
server_socket_free(struct server_socket *ss);

View File

@ -29,6 +29,7 @@
#include "icy_server.h"
#include "fd_util.h"
#include "ServerSocket.hxx"
#include "Main.hxx"
#include <assert.h>
@ -134,7 +135,8 @@ httpd_output_init(const struct config_param *param,
/* set up bind_to_address */
httpd->server_socket = server_socket_new(httpd_listen_in_event, httpd);
httpd->server_socket = server_socket_new(*main_loop,
httpd_listen_in_event, httpd);
const char *bind_to_address =
config_get_block_string(param, "bind_to_address", NULL);