Commit e83f805b authored by Max Kellermann's avatar Max Kellermann

Main, IOThread: move GMainLoop setup code to class EventLoop

parent be98afe3
......@@ -353,7 +353,8 @@ libutil_a_SOURCES = \
# Event loop library
libevent_a_SOURCES = \
src/event/WakeFD.cxx
src/event/WakeFD.cxx src/event/WakeFD.hxx \
src/event/Loop.hxx
# PCM library
......
......@@ -20,6 +20,7 @@
#include "config.h"
#include "ClientInternal.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include <assert.h>
......@@ -83,7 +84,7 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition,
case COMMAND_RETURN_KILL:
client_close(client);
g_main_loop_quit(main_loop);
main_loop->Break();
return false;
case COMMAND_RETURN_CLOSE:
......
......@@ -17,9 +17,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "IOThread.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "event/Loop.hxx"
#include <assert.h>
......@@ -27,8 +29,7 @@ static struct {
Mutex mutex;
Cond cond;
GMainContext *context;
GMainLoop *loop;
EventLoop *loop;
GThread *thread;
} io;
......@@ -36,10 +37,9 @@ void
io_thread_run(void)
{
assert(io_thread_inside());
assert(io.context != NULL);
assert(io.loop != NULL);
g_main_loop_run(io.loop);
io.loop->Run();
}
static gpointer
......@@ -57,18 +57,15 @@ io_thread_func(G_GNUC_UNUSED gpointer arg)
void
io_thread_init(void)
{
assert(io.context == NULL);
assert(io.loop == NULL);
assert(io.thread == NULL);
io.context = g_main_context_new();
io.loop = g_main_loop_new(io.context, false);
io.loop = new EventLoop();
}
bool
io_thread_start(GError **error_r)
{
assert(io.context != NULL);
assert(io.loop != NULL);
assert(io.thread == NULL);
......@@ -86,7 +83,7 @@ io_thread_quit(void)
{
assert(io.loop != NULL);
g_main_loop_quit(io.loop);
io.loop->Break();
}
void
......@@ -98,17 +95,15 @@ io_thread_deinit(void)
g_thread_join(io.thread);
}
if (io.loop != NULL)
g_main_loop_unref(io.loop);
if (io.context != NULL)
g_main_context_unref(io.context);
delete io.loop;
}
GMainContext *
io_thread_context(void)
EventLoop &
io_thread_get()
{
return io.context;
assert(io.loop != nullptr);
return *io.loop;
}
bool
......@@ -117,35 +112,6 @@ io_thread_inside(void)
return io.thread != NULL && g_thread_self() == io.thread;
}
guint
io_thread_idle_add(GSourceFunc function, gpointer data)
{
GSource *source = g_idle_source_new();
g_source_set_callback(source, function, data, NULL);
guint id = g_source_attach(source, io.context);
g_source_unref(source);
return id;
}
GSource *
io_thread_timeout_add(guint interval_ms, GSourceFunc function, gpointer data)
{
GSource *source = g_timeout_source_new(interval_ms);
g_source_set_callback(source, function, data, NULL);
g_source_attach(source, io.context);
return source;
}
GSource *
io_thread_timeout_add_seconds(guint interval,
GSourceFunc function, gpointer data)
{
GSource *source = g_timeout_source_new_seconds(interval);
g_source_set_callback(source, function, data, NULL);
g_source_attach(source, io.context);
return source;
}
struct call_data {
GThreadFunc function;
gpointer data;
......@@ -186,7 +152,7 @@ io_thread_call(GThreadFunc function, gpointer _data)
nullptr,
};
io_thread_idle_add(io_thread_call_func, &data);
io.loop->AddIdle(io_thread_call_func, &data);
io.mutex.lock();
while (!data.done)
......
......@@ -24,6 +24,8 @@
#include <glib.h>
class EventLoop;
void
io_thread_init(void);
......@@ -50,8 +52,8 @@ void
io_thread_deinit(void);
gcc_pure
GMainContext *
io_thread_context(void);
EventLoop &
io_thread_get();
/**
* Is the current thread the I/O thread?
......@@ -60,18 +62,6 @@ gcc_pure
bool
io_thread_inside(void);
guint
io_thread_idle_add(GSourceFunc function, gpointer data);
gcc_malloc
GSource *
io_thread_timeout_add(guint interval_ms, GSourceFunc function, gpointer data);
gcc_malloc
GSource *
io_thread_timeout_add_seconds(guint interval,
GSourceFunc function, gpointer data);
/**
* Call a function synchronously in the I/O thread.
*/
......
......@@ -20,6 +20,8 @@
#include "config.h"
#include "InotifyQueue.hxx"
#include "UpdateGlue.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include <list>
#include <string>
......@@ -93,8 +95,9 @@ mpd_inotify_enqueue(const char *uri_utf8)
{
if (queue_source_id != 0)
g_source_remove(queue_source_id);
queue_source_id = g_timeout_add_seconds(INOTIFY_UPDATE_DELAY_S,
mpd_inotify_run_update, NULL);
queue_source_id = main_loop->AddTimeoutSeconds(INOTIFY_UPDATE_DELAY_S,
mpd_inotify_run_update,
nullptr);
for (auto i = inotify_queue.begin(), end = inotify_queue.end();
i != end;) {
......
......@@ -45,6 +45,7 @@
#include "Log.hxx"
#include "GlobalEvents.hxx"
#include "InputInit.hxx"
#include "event/Loop.hxx"
#include "IOThread.hxx"
extern "C" {
......@@ -96,7 +97,7 @@ enum {
};
GThread *main_task;
GMainLoop *main_loop;
EventLoop *main_loop;
Partition *global_partition;
......@@ -332,7 +333,7 @@ idle_event_emitted(void)
static void
shutdown_event_emitted(void)
{
g_main_loop_quit(main_loop);
main_loop->Break();
}
int main(int argc, char *argv[])
......@@ -401,7 +402,7 @@ int mpd_main(int argc, char *argv[])
daemonize_set_user();
main_task = g_thread_self();
main_loop = g_main_loop_new(NULL, FALSE);
main_loop = new EventLoop(EventLoop::Default());
GlobalEvents::Initialize();
GlobalEvents::Register(GlobalEvents::IDLE, idle_event_emitted);
......@@ -504,7 +505,7 @@ int mpd_main(int argc, char *argv[])
#endif
/* run the main loop */
g_main_loop_run(main_loop);
main_loop->Run();
#ifdef WIN32
win32_app_stopping();
......@@ -512,7 +513,7 @@ int mpd_main(int argc, char *argv[])
/* cleanup */
g_main_loop_unref(main_loop);
delete main_loop;
#ifdef ENABLE_INOTIFY
mpd_inotify_finish();
......
......@@ -22,9 +22,11 @@
#include <glib.h>
class EventLoop;
extern GThread *main_task;
extern GMainLoop *main_loop;
extern EventLoop *main_loop;
extern struct Partition *global_partition;
......
......@@ -24,6 +24,7 @@
#include "Log.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include "GlobalEvents.hxx"
#include "mpd_error.h"
......@@ -35,7 +36,7 @@
static void exit_signal_handler(G_GNUC_UNUSED int signum)
{
g_main_loop_quit(main_loop);
main_loop->Break();
}
static void reload_signal_handler(G_GNUC_UNUSED int signum)
......
......@@ -24,6 +24,8 @@
#include "TextFile.hxx"
#include "Partition.hxx"
#include "Volume.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include <glib.h>
#include <assert.h>
......@@ -137,9 +139,9 @@ state_file_init(const char *path, Partition &partition)
state_file_path = g_strdup(path);
state_file_read(partition);
save_state_source_id = g_timeout_add_seconds(5 * 60,
timer_save_state_file,
&partition);
save_state_source_id =
main_loop->AddTimeoutSeconds(5 * 60, timer_save_state_file,
&partition);
}
void
......
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_EVENT_LOOP_HXX
#define MPD_EVENT_LOOP_HXX
#include "check.h"
#include "gcc.h"
#include <glib.h>
class EventLoop {
GMainContext *context;
GMainLoop *loop;
public:
EventLoop()
:context(g_main_context_new()),
loop(g_main_loop_new(context, false)) {}
struct Default {};
EventLoop(gcc_unused Default _dummy)
:context(g_main_context_ref(g_main_context_default())),
loop(g_main_loop_new(context, false)) {}
~EventLoop() {
g_main_loop_unref(loop);
g_main_context_unref(context);
}
GMainContext *GetContext() {
return context;
}
void Break() {
g_main_loop_quit(loop);
}
void Run() {
g_main_loop_run(loop);
}
guint AddIdle(GSourceFunc function, gpointer data) {
GSource *source = g_idle_source_new();
g_source_set_callback(source, function, data, NULL);
guint id = g_source_attach(source, GetContext());
g_source_unref(source);
return id;
}
guint AddTimeout(guint interval_ms,
GSourceFunc function, gpointer data) {
GSource *source = g_timeout_source_new(interval_ms);
g_source_set_callback(source, function, data, nullptr);
guint id = g_source_attach(source, GetContext());
g_source_unref(source);
return id;
}
guint AddTimeoutSeconds(guint interval_s,
GSourceFunc function, gpointer data) {
GSource *source = g_timeout_source_new_seconds(interval_s);
g_source_set_callback(source, function, data, nullptr);
guint id = g_source_attach(source, GetContext());
g_source_unref(source);
return id;
}
};
#endif /* MAIN_NOTIFY_H */
......@@ -28,6 +28,7 @@ extern "C" {
#include "input_internal.h"
}
#include "event/Loop.hxx"
#include "IOThread.hxx"
#include "glib_compat.h"
......@@ -716,7 +717,8 @@ input_curl_init(const struct config_param *param,
}
curl.source = g_source_new(&curl_source_funcs, sizeof(*curl.source));
curl.source_id = g_source_attach(curl.source, io_thread_context());
curl.source_id = g_source_attach(curl.source,
io_thread_get().GetContext());
return true;
}
......
......@@ -26,6 +26,7 @@ extern "C" {
}
#include "IOThread.hxx"
#include "event/Loop.hxx"
#include "conf.h"
extern "C" {
......@@ -105,7 +106,7 @@ input_soup_init(const struct config_param *param, GError **error_r)
soup_session_async_new_with_options(SOUP_SESSION_PROXY_URI,
soup_proxy,
SOUP_SESSION_ASYNC_CONTEXT,
io_thread_context(),
io_thread_get().GetContext(),
NULL);
return true;
......
......@@ -19,18 +19,19 @@
#include "config.h"
#include "InotifySource.hxx"
#include "event/Loop.hxx"
#include <glib.h>
#include <sys/inotify.h>
#include <signal.h>
static GMainLoop *main_loop;
static EventLoop *event_loop;
static void
exit_signal_handler(G_GNUC_UNUSED int signum)
{
g_main_loop_quit(main_loop);
event_loop->Break();
}
enum {
......@@ -78,7 +79,7 @@ int main(int argc, char **argv)
return 2;
}
main_loop = g_main_loop_new(NULL, false);
event_loop = new EventLoop(EventLoop::Default());
struct sigaction sa;
sa.sa_flags = 0;
......@@ -87,8 +88,8 @@ int main(int argc, char **argv)
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
g_main_loop_run(main_loop);
g_main_loop_unref(main_loop);
event_loop->Run();
mpd_inotify_source_free(source);
delete event_loop;
}
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