io_thread: add helper functions
This commit is contained in:
@@ -18,10 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "io_thread.h"
|
#include "io_thread.h"
|
||||||
|
#include "glib_compat.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
GMutex *mutex;
|
||||||
|
GCond *cond;
|
||||||
|
|
||||||
GMainContext *context;
|
GMainContext *context;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
GThread *thread;
|
GThread *thread;
|
||||||
@@ -44,6 +48,8 @@ io_thread_init(void)
|
|||||||
assert(io.loop == NULL);
|
assert(io.loop == NULL);
|
||||||
assert(io.thread == NULL);
|
assert(io.thread == NULL);
|
||||||
|
|
||||||
|
io.mutex = g_mutex_new();
|
||||||
|
io.cond = g_cond_new();
|
||||||
io.context = g_main_context_new();
|
io.context = g_main_context_new();
|
||||||
io.loop = g_main_loop_new(io.context, false);
|
io.loop = g_main_loop_new(io.context, false);
|
||||||
}
|
}
|
||||||
@@ -77,6 +83,9 @@ io_thread_deinit(void)
|
|||||||
|
|
||||||
if (io.context != NULL)
|
if (io.context != NULL)
|
||||||
g_main_context_unref(io.context);
|
g_main_context_unref(io.context);
|
||||||
|
|
||||||
|
g_cond_free(io.cond);
|
||||||
|
g_mutex_free(io.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
GMainContext *
|
GMainContext *
|
||||||
@@ -85,3 +94,65 @@ io_thread_context(void)
|
|||||||
return io.context;
|
return io.context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
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);
|
||||||
|
guint id = g_source_attach(source, io.context);
|
||||||
|
g_source_unref(source);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct call_data {
|
||||||
|
GThreadFunc function;
|
||||||
|
gpointer data;
|
||||||
|
bool done;
|
||||||
|
gpointer result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
io_thread_call_func(gpointer _data)
|
||||||
|
{
|
||||||
|
struct call_data *data = _data;
|
||||||
|
|
||||||
|
gpointer result = data->function(data->data);
|
||||||
|
|
||||||
|
g_mutex_lock(io.mutex);
|
||||||
|
data->done = true;
|
||||||
|
data->result = result;
|
||||||
|
g_cond_broadcast(io.cond);
|
||||||
|
g_mutex_unlock(io.mutex);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpointer
|
||||||
|
io_thread_call(GThreadFunc function, gpointer _data)
|
||||||
|
{
|
||||||
|
struct call_data data = {
|
||||||
|
.function = function,
|
||||||
|
.data = _data,
|
||||||
|
.done = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
io_thread_idle_add(io_thread_call_func, &data);
|
||||||
|
|
||||||
|
g_mutex_lock(io.mutex);
|
||||||
|
while (!data.done)
|
||||||
|
g_cond_wait(io.cond, io.mutex);
|
||||||
|
g_mutex_unlock(io.mutex);
|
||||||
|
|
||||||
|
return data.result;
|
||||||
|
}
|
||||||
|
@@ -36,4 +36,17 @@ G_GNUC_PURE
|
|||||||
GMainContext *
|
GMainContext *
|
||||||
io_thread_context(void);
|
io_thread_context(void);
|
||||||
|
|
||||||
|
guint
|
||||||
|
io_thread_idle_add(GSourceFunc function, gpointer data);
|
||||||
|
|
||||||
|
guint
|
||||||
|
io_thread_timeout_add_seconds(guint interval,
|
||||||
|
GSourceFunc function, gpointer data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a function synchronously in the I/O thread.
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
io_thread_call(GThreadFunc function, gpointer data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user