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 = \ ...@@ -353,7 +353,8 @@ libutil_a_SOURCES = \
# Event loop library # Event loop library
libevent_a_SOURCES = \ libevent_a_SOURCES = \
src/event/WakeFD.cxx src/event/WakeFD.cxx src/event/WakeFD.hxx \
src/event/Loop.hxx
# PCM library # PCM library
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "ClientInternal.hxx" #include "ClientInternal.hxx"
#include "Main.hxx" #include "Main.hxx"
#include "event/Loop.hxx"
#include <assert.h> #include <assert.h>
...@@ -83,7 +84,7 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition, ...@@ -83,7 +84,7 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition,
case COMMAND_RETURN_KILL: case COMMAND_RETURN_KILL:
client_close(client); client_close(client);
g_main_loop_quit(main_loop); main_loop->Break();
return false; return false;
case COMMAND_RETURN_CLOSE: case COMMAND_RETURN_CLOSE:
......
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "config.h"
#include "IOThread.hxx" #include "IOThread.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "event/Loop.hxx"
#include <assert.h> #include <assert.h>
...@@ -27,8 +29,7 @@ static struct { ...@@ -27,8 +29,7 @@ static struct {
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
GMainContext *context; EventLoop *loop;
GMainLoop *loop;
GThread *thread; GThread *thread;
} io; } io;
...@@ -36,10 +37,9 @@ void ...@@ -36,10 +37,9 @@ void
io_thread_run(void) io_thread_run(void)
{ {
assert(io_thread_inside()); assert(io_thread_inside());
assert(io.context != NULL);
assert(io.loop != NULL); assert(io.loop != NULL);
g_main_loop_run(io.loop); io.loop->Run();
} }
static gpointer static gpointer
...@@ -57,18 +57,15 @@ io_thread_func(G_GNUC_UNUSED gpointer arg) ...@@ -57,18 +57,15 @@ io_thread_func(G_GNUC_UNUSED gpointer arg)
void void
io_thread_init(void) io_thread_init(void)
{ {
assert(io.context == NULL);
assert(io.loop == NULL); assert(io.loop == NULL);
assert(io.thread == NULL); assert(io.thread == NULL);
io.context = g_main_context_new(); io.loop = new EventLoop();
io.loop = g_main_loop_new(io.context, false);
} }
bool bool
io_thread_start(GError **error_r) io_thread_start(GError **error_r)
{ {
assert(io.context != NULL);
assert(io.loop != NULL); assert(io.loop != NULL);
assert(io.thread == NULL); assert(io.thread == NULL);
...@@ -86,7 +83,7 @@ io_thread_quit(void) ...@@ -86,7 +83,7 @@ io_thread_quit(void)
{ {
assert(io.loop != NULL); assert(io.loop != NULL);
g_main_loop_quit(io.loop); io.loop->Break();
} }
void void
...@@ -98,17 +95,15 @@ io_thread_deinit(void) ...@@ -98,17 +95,15 @@ io_thread_deinit(void)
g_thread_join(io.thread); g_thread_join(io.thread);
} }
if (io.loop != NULL) delete io.loop;
g_main_loop_unref(io.loop);
if (io.context != NULL)
g_main_context_unref(io.context);
} }
GMainContext * EventLoop &
io_thread_context(void) io_thread_get()
{ {
return io.context; assert(io.loop != nullptr);
return *io.loop;
} }
bool bool
...@@ -117,35 +112,6 @@ io_thread_inside(void) ...@@ -117,35 +112,6 @@ io_thread_inside(void)
return io.thread != NULL && g_thread_self() == io.thread; 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 { struct call_data {
GThreadFunc function; GThreadFunc function;
gpointer data; gpointer data;
...@@ -186,7 +152,7 @@ io_thread_call(GThreadFunc function, gpointer _data) ...@@ -186,7 +152,7 @@ io_thread_call(GThreadFunc function, gpointer _data)
nullptr, nullptr,
}; };
io_thread_idle_add(io_thread_call_func, &data); io.loop->AddIdle(io_thread_call_func, &data);
io.mutex.lock(); io.mutex.lock();
while (!data.done) while (!data.done)
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <glib.h> #include <glib.h>
class EventLoop;
void void
io_thread_init(void); io_thread_init(void);
...@@ -50,8 +52,8 @@ void ...@@ -50,8 +52,8 @@ void
io_thread_deinit(void); io_thread_deinit(void);
gcc_pure gcc_pure
GMainContext * EventLoop &
io_thread_context(void); io_thread_get();
/** /**
* Is the current thread the I/O thread? * Is the current thread the I/O thread?
...@@ -60,18 +62,6 @@ gcc_pure ...@@ -60,18 +62,6 @@ gcc_pure
bool bool
io_thread_inside(void); 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. * Call a function synchronously in the I/O thread.
*/ */
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "config.h" #include "config.h"
#include "InotifyQueue.hxx" #include "InotifyQueue.hxx"
#include "UpdateGlue.hxx" #include "UpdateGlue.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include <list> #include <list>
#include <string> #include <string>
...@@ -93,8 +95,9 @@ mpd_inotify_enqueue(const char *uri_utf8) ...@@ -93,8 +95,9 @@ mpd_inotify_enqueue(const char *uri_utf8)
{ {
if (queue_source_id != 0) if (queue_source_id != 0)
g_source_remove(queue_source_id); g_source_remove(queue_source_id);
queue_source_id = g_timeout_add_seconds(INOTIFY_UPDATE_DELAY_S, queue_source_id = main_loop->AddTimeoutSeconds(INOTIFY_UPDATE_DELAY_S,
mpd_inotify_run_update, NULL); mpd_inotify_run_update,
nullptr);
for (auto i = inotify_queue.begin(), end = inotify_queue.end(); for (auto i = inotify_queue.begin(), end = inotify_queue.end();
i != end;) { i != end;) {
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "Log.hxx" #include "Log.hxx"
#include "GlobalEvents.hxx" #include "GlobalEvents.hxx"
#include "InputInit.hxx" #include "InputInit.hxx"
#include "event/Loop.hxx"
#include "IOThread.hxx" #include "IOThread.hxx"
extern "C" { extern "C" {
...@@ -96,7 +97,7 @@ enum { ...@@ -96,7 +97,7 @@ enum {
}; };
GThread *main_task; GThread *main_task;
GMainLoop *main_loop; EventLoop *main_loop;
Partition *global_partition; Partition *global_partition;
...@@ -332,7 +333,7 @@ idle_event_emitted(void) ...@@ -332,7 +333,7 @@ idle_event_emitted(void)
static void static void
shutdown_event_emitted(void) shutdown_event_emitted(void)
{ {
g_main_loop_quit(main_loop); main_loop->Break();
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -401,7 +402,7 @@ int mpd_main(int argc, char *argv[]) ...@@ -401,7 +402,7 @@ int mpd_main(int argc, char *argv[])
daemonize_set_user(); daemonize_set_user();
main_task = g_thread_self(); main_task = g_thread_self();
main_loop = g_main_loop_new(NULL, FALSE); main_loop = new EventLoop(EventLoop::Default());
GlobalEvents::Initialize(); GlobalEvents::Initialize();
GlobalEvents::Register(GlobalEvents::IDLE, idle_event_emitted); GlobalEvents::Register(GlobalEvents::IDLE, idle_event_emitted);
...@@ -504,7 +505,7 @@ int mpd_main(int argc, char *argv[]) ...@@ -504,7 +505,7 @@ int mpd_main(int argc, char *argv[])
#endif #endif
/* run the main loop */ /* run the main loop */
g_main_loop_run(main_loop); main_loop->Run();
#ifdef WIN32 #ifdef WIN32
win32_app_stopping(); win32_app_stopping();
...@@ -512,7 +513,7 @@ int mpd_main(int argc, char *argv[]) ...@@ -512,7 +513,7 @@ int mpd_main(int argc, char *argv[])
/* cleanup */ /* cleanup */
g_main_loop_unref(main_loop); delete main_loop;
#ifdef ENABLE_INOTIFY #ifdef ENABLE_INOTIFY
mpd_inotify_finish(); mpd_inotify_finish();
......
...@@ -22,9 +22,11 @@ ...@@ -22,9 +22,11 @@
#include <glib.h> #include <glib.h>
class EventLoop;
extern GThread *main_task; extern GThread *main_task;
extern GMainLoop *main_loop; extern EventLoop *main_loop;
extern struct Partition *global_partition; extern struct Partition *global_partition;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "Log.hxx" #include "Log.hxx"
#include "Main.hxx" #include "Main.hxx"
#include "event/Loop.hxx"
#include "GlobalEvents.hxx" #include "GlobalEvents.hxx"
#include "mpd_error.h" #include "mpd_error.h"
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
static void exit_signal_handler(G_GNUC_UNUSED int signum) 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) static void reload_signal_handler(G_GNUC_UNUSED int signum)
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "TextFile.hxx" #include "TextFile.hxx"
#include "Partition.hxx" #include "Partition.hxx"
#include "Volume.hxx" #include "Volume.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include <glib.h> #include <glib.h>
#include <assert.h> #include <assert.h>
...@@ -137,9 +139,9 @@ state_file_init(const char *path, Partition &partition) ...@@ -137,9 +139,9 @@ state_file_init(const char *path, Partition &partition)
state_file_path = g_strdup(path); state_file_path = g_strdup(path);
state_file_read(partition); state_file_read(partition);
save_state_source_id = g_timeout_add_seconds(5 * 60, save_state_source_id =
timer_save_state_file, main_loop->AddTimeoutSeconds(5 * 60, timer_save_state_file,
&partition); &partition);
} }
void 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" { ...@@ -28,6 +28,7 @@ extern "C" {
#include "input_internal.h" #include "input_internal.h"
} }
#include "event/Loop.hxx"
#include "IOThread.hxx" #include "IOThread.hxx"
#include "glib_compat.h" #include "glib_compat.h"
...@@ -716,7 +717,8 @@ input_curl_init(const struct config_param *param, ...@@ -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 = 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; return true;
} }
......
...@@ -26,6 +26,7 @@ extern "C" { ...@@ -26,6 +26,7 @@ extern "C" {
} }
#include "IOThread.hxx" #include "IOThread.hxx"
#include "event/Loop.hxx"
#include "conf.h" #include "conf.h"
extern "C" { extern "C" {
...@@ -105,7 +106,7 @@ input_soup_init(const struct config_param *param, GError **error_r) ...@@ -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_session_async_new_with_options(SOUP_SESSION_PROXY_URI,
soup_proxy, soup_proxy,
SOUP_SESSION_ASYNC_CONTEXT, SOUP_SESSION_ASYNC_CONTEXT,
io_thread_context(), io_thread_get().GetContext(),
NULL); NULL);
return true; return true;
......
...@@ -19,18 +19,19 @@ ...@@ -19,18 +19,19 @@
#include "config.h" #include "config.h"
#include "InotifySource.hxx" #include "InotifySource.hxx"
#include "event/Loop.hxx"
#include <glib.h> #include <glib.h>
#include <sys/inotify.h> #include <sys/inotify.h>
#include <signal.h> #include <signal.h>
static GMainLoop *main_loop; static EventLoop *event_loop;
static void static void
exit_signal_handler(G_GNUC_UNUSED int signum) exit_signal_handler(G_GNUC_UNUSED int signum)
{ {
g_main_loop_quit(main_loop); event_loop->Break();
} }
enum { enum {
...@@ -78,7 +79,7 @@ int main(int argc, char **argv) ...@@ -78,7 +79,7 @@ int main(int argc, char **argv)
return 2; return 2;
} }
main_loop = g_main_loop_new(NULL, false); event_loop = new EventLoop(EventLoop::Default());
struct sigaction sa; struct sigaction sa;
sa.sa_flags = 0; sa.sa_flags = 0;
...@@ -87,8 +88,8 @@ int main(int argc, char **argv) ...@@ -87,8 +88,8 @@ int main(int argc, char **argv)
sigaction(SIGINT, &sa, NULL); sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL); sigaction(SIGTERM, &sa, NULL);
g_main_loop_run(main_loop); event_loop->Run();
g_main_loop_unref(main_loop);
mpd_inotify_source_free(source); 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