aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Listen.cxx4
-rw-r--r--src/Main.cxx6
-rw-r--r--src/ServerSocket.cxx78
-rw-r--r--src/ServerSocket.hxx4
-rw-r--r--src/output/HttpdOutputPlugin.cxx4
5 files changed, 40 insertions, 56 deletions
diff --git a/src/Listen.cxx b/src/Listen.cxx
index 6b298769a..7bc10dc18 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -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;
diff --git a/src/Main.cxx b/src/Main.cxx
index e0083bff7..917d89457 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -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);
diff --git a/src/ServerSocket.cxx b/src/ServerSocket.cxx
index 3a709e140..7f14168a8 100644
--- a/src/ServerSocket.cxx
+++ b/src/ServerSocket.cxx
@@ -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,
@@ -310,17 +299,6 @@ server_socket_open(struct server_socket *ss, GError **error_r)
}
void
-OneServerSocket::Close()
-{
- if (fd < 0)
- return;
-
- g_source_remove(source_id);
- close_socket(fd);
- fd = -1;
-}
-
-void
server_socket::Close()
{
for (auto &i : sockets)
@@ -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();
diff --git a/src/ServerSocket.hxx b/src/ServerSocket.hxx
index f09fd7e9e..eea4b0851 100644
--- a/src/ServerSocket.hxx
+++ b/src/ServerSocket.hxx
@@ -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);
diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx
index 075e0ea5e..d1a1a36df 100644
--- a/src/output/HttpdOutputPlugin.cxx
+++ b/src/output/HttpdOutputPlugin.cxx
@@ -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);