summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVolodymyr Brynza <v.brynza@samsung.com>2016-12-19 22:22:14 +0200
committerJeongmo Yang <jm80.yang@samsung.com>2016-12-20 17:27:22 +0900
commit7a283dbb2ef34dc24492029f39ba182c3fee1326 (patch)
tree4fd1d78e963447ea6ee1a0614f275caf50aea1c4 /src
parentb6a583e98aaa2b09fb2d54dbf198684831d82694 (diff)
downloadmurphy-7a283dbb2ef34dc24492029f39ba182c3fee1326.tar.gz
murphy-7a283dbb2ef34dc24492029f39ba182c3fee1326.tar.bz2
murphy-7a283dbb2ef34dc24492029f39ba182c3fee1326.zip
Change-Id: Ic2aad19a9bf9269955e825c8b77af75ffeb96efa Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/common/glib-glue.c108
-rw-r--r--src/common/mainloop.c19
2 files changed, 113 insertions, 14 deletions
diff --git a/src/common/glib-glue.c b/src/common/glib-glue.c
index bea7f98..e2097d5 100644
--- a/src/common/glib-glue.c
+++ b/src/common/glib-glue.c
@@ -36,8 +36,13 @@
#include <murphy/common/mainloop.h>
+static GMutex g_murphy_glue_callback_lock;
+static GMutex g_murphy_glue_internal_lock;
+
+
typedef struct {
GMainLoop *gml;
+ GThread *worker;
} glib_glue_t;
@@ -136,6 +141,7 @@ static void remove_source(void *glue_data, guint id)
static gboolean io_cb(GIOChannel *ioc, GIOCondition cond, gpointer user_data)
{
+ g_mutex_lock(&g_murphy_glue_callback_lock);
io_t *io = (io_t *)user_data;
mrp_io_event_t events = MRP_IO_EVENT_NONE;
int fd = g_io_channel_unix_get_fd(ioc);
@@ -151,6 +157,7 @@ static gboolean io_cb(GIOChannel *ioc, GIOCondition cond, gpointer user_data)
io->cb(io->glue_data, io, fd, events, io->user_data);
+ g_mutex_unlock(&g_murphy_glue_callback_lock);
return TRUE;
}
@@ -164,10 +171,13 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events,
GIOChannel *ioc;
io_t *io;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
ioc = g_io_channel_unix_new(fd);
- if (ioc == NULL)
+ if (ioc == NULL) {
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return NULL;
+ }
io = mrp_allocz(sizeof(*io));
@@ -187,6 +197,7 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events,
io->user_data = user_data;
io->glue_data = glue_data;
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return io;
}
else {
@@ -195,6 +206,7 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events,
}
}
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return NULL;
}
@@ -203,24 +215,31 @@ static void del_io(void *glue_data, void *id)
{
io_t *io = (io_t *)id;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
remove_source(glue_data, io->gl_iow);
g_io_channel_unref(io->gl_ioc);
mrp_free(io);
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
}
static gboolean timer_cb(gpointer user_data)
{
- if (user_data == NULL)
+ if (user_data == NULL) {
return FALSE;
+ }
+ g_mutex_lock(&g_murphy_glue_callback_lock);
tmr_t *t = (tmr_t *)user_data;
- if (t->cb == NULL)
+ if (t->cb == NULL) {
+ g_mutex_unlock(&g_murphy_glue_callback_lock);
return FALSE;
+ }
t->cb(t->glue_data, t, t->user_data);
+ g_mutex_unlock(&g_murphy_glue_callback_lock);
return TRUE;
}
@@ -231,6 +250,7 @@ static void *add_timer(void *glue_data, unsigned int msecs,
{
tmr_t *t;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
t = mrp_allocz(sizeof(*t));
if (t != NULL) {
@@ -241,12 +261,14 @@ static void *add_timer(void *glue_data, unsigned int msecs,
t->user_data = user_data;
t->glue_data = glue_data;
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return t;
}
else
mrp_free(t);
}
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return NULL;
}
@@ -255,8 +277,10 @@ static void del_timer(void *glue_data, void *id)
{
tmr_t *t = (tmr_t *)id;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
remove_source(glue_data, t->gl_t);
mrp_free(t);
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
}
@@ -264,25 +288,32 @@ static void mod_timer(void *glue_data, void *id, unsigned int msecs)
{
tmr_t *t = (tmr_t *)id;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
if (t != NULL) {
remove_source(glue_data, t->gl_t);
t->gl_t = add_timeout(glue_data, (GSourceFunc)timer_cb, msecs, t);
}
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
}
static gboolean defer_cb(void *user_data)
{
- if (user_data == NULL)
+ if (user_data == NULL) {
return FALSE;
+ }
+ g_mutex_lock(&g_murphy_glue_callback_lock);
dfr_t *d = (dfr_t *)user_data;
- if (d->cb == NULL)
+ if (d->cb == NULL) {
+ g_mutex_unlock(&g_murphy_glue_callback_lock);
return FALSE;
+ }
d->cb(d->glue_data, d, d->user_data);
+ g_mutex_unlock(&g_murphy_glue_callback_lock);
return TRUE;
}
@@ -293,6 +324,7 @@ static void *add_defer(void *glue_data,
{
dfr_t *d;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
d = mrp_allocz(sizeof(*d));
if (d != NULL) {
@@ -303,12 +335,14 @@ static void *add_defer(void *glue_data,
d->user_data = user_data;
d->glue_data = glue_data;
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return d;
}
else
mrp_free(d);
}
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
return NULL;
}
@@ -317,10 +351,12 @@ static void del_defer(void *glue_data, void *id)
{
dfr_t *d = (dfr_t *)id;
+ g_mutex_lock(&g_murphy_glue_internal_lock);
if (d->gl_t != 0)
remove_source(glue_data, d->gl_t);
mrp_free(d);
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
}
@@ -328,9 +364,11 @@ static void mod_defer(void *glue_data, void *id, int enabled)
{
dfr_t *d = (dfr_t *)id;
- if (d == NULL)
+ if (d == NULL) {
return;
+ }
+ g_mutex_lock(&g_murphy_glue_internal_lock);
if (enabled && !d->gl_t) {
d->gl_t = add_timeout(glue_data, (GSourceFunc)defer_cb, 0, d);
}
@@ -338,14 +376,32 @@ static void mod_defer(void *glue_data, void *id, int enabled)
remove_source(glue_data, d->gl_t);
d->gl_t = 0;
}
+ g_mutex_unlock(&g_murphy_glue_internal_lock);
}
static void unregister(void *data)
{
glib_glue_t *glue = (glib_glue_t *)data;
+ GMainContext *def_ctx = g_main_context_default();
+ GMainContext *loop_ctx = g_main_loop_get_context(glue->gml);
+ if (loop_ctx && def_ctx != loop_ctx) {
+ GSource *idle = g_idle_source_new();
+
+ g_source_set_callback(idle, (GSourceFunc) g_main_loop_quit,
+ glue->gml, NULL);
+
+ g_source_attach(idle, g_main_loop_get_context(glue->gml));
+ g_source_unref(idle);
+ g_thread_join(glue->worker);
+ g_thread_unref(glue->worker);
+ glue->worker = NULL;
+ }
- g_main_loop_unref(glue->gml);
+ if (glue->gml) {
+ g_main_loop_unref(glue->gml);
+ glue->gml = NULL;
+ }
mrp_free(glue);
}
@@ -363,6 +419,21 @@ static mrp_superloop_ops_t glib_ops = {
.unregister = unregister,
};
+static gpointer
+thread_main (gpointer data)
+{
+ glib_glue_t *glue = (glib_glue_t *)data;
+ GMainContext *thread_main_context = g_main_loop_get_context(glue->gml);
+
+ /* Set up the thread’s context and run it. */
+ g_main_context_push_thread_default (thread_main_context);
+
+ g_main_loop_run (glue->gml);
+
+ g_main_context_pop_thread_default (thread_main_context);
+
+ return NULL;
+}
int mrp_mainloop_register_with_glib(mrp_mainloop_t *ml, GMainLoop *gml)
{
@@ -373,8 +444,15 @@ int mrp_mainloop_register_with_glib(mrp_mainloop_t *ml, GMainLoop *gml)
if (glue != NULL) {
glue->gml = g_main_loop_ref(gml);
- if (mrp_set_superloop(ml, &glib_ops, glue))
+ if (mrp_set_superloop(ml, &glib_ops, glue)) {
+ /* Create new thread for context iteration only in case when
+ * glue context isn't default */
+ GMainContext *def_ctx = g_main_context_default();
+ GMainContext *loop_ctx = g_main_loop_get_context(glue->gml);
+ if (loop_ctx && def_ctx != loop_ctx)
+ glue->worker = g_thread_new(NULL, thread_main, glue);
return TRUE;
+ }
else {
g_main_loop_unref(gml);
mrp_free(glue);
@@ -408,3 +486,17 @@ mrp_mainloop_t *mrp_mainloop_glib_get(GMainLoop *gml)
return NULL;
}
+
+
+MRP_INIT static void mrp_main_loop_init_lock()
+{
+ g_mutex_init(&g_murphy_glue_callback_lock);
+ g_mutex_init(&g_murphy_glue_internal_lock);
+}
+
+
+MRP_EXIT static void mrp_main_loop_clear_lock()
+{
+ g_mutex_clear(&g_murphy_glue_callback_lock);
+ g_mutex_clear(&g_murphy_glue_internal_lock);
+}
diff --git a/src/common/mainloop.c b/src/common/mainloop.c
index 5702c15..bf46cd8 100644
--- a/src/common/mainloop.c
+++ b/src/common/mainloop.c
@@ -1291,13 +1291,20 @@ static void super_work_cb(void *super_data, void *id, void *user_data)
ops->mod_defer(ml->super_data, ml->work, FALSE);
}
else {
- ops->del_io(ml->super_data, ml->iow);
- ops->del_timer(ml->super_data, ml->timer);
- ops->del_defer(ml->super_data, ml->work);
+ if (ml->iow != NULL) {
+ ops->del_io(ml->super_data, ml->iow);
+ ml->iow = NULL;
+ }
+
+ if (ml->work != NULL) {
+ ops->del_defer(ml->super_data, ml->work);
+ ml->work = NULL;
+ }
- ml->iow = NULL;
- ml->timer = NULL;
- ml->work = NULL;
+ if (ml->timer != NULL) {
+ ops->del_timer(ml->super_data, ml->timer);
+ ml->timer = NULL;
+ }
}
}