diff options
author | Volodymyr Brynza <v.brynza@samsung.com> | 2017-05-12 14:33:52 +0300 |
---|---|---|
committer | Volodymyr Brynza <v.brynza@samsung.com> | 2017-05-12 14:33:52 +0300 |
commit | e25ee486b2e66a00d0144a83bb4e2a8210375a31 (patch) | |
tree | f18df3bae7cd10c5a757b2554d84e24601990a1c | |
parent | 2c8263babf1f094e8dfe8b17bf0864e301e41571 (diff) | |
download | murphy-e25ee486b2e66a00d0144a83bb4e2a8210375a31.tar.gz murphy-e25ee486b2e66a00d0144a83bb4e2a8210375a31.tar.bz2 murphy-e25ee486b2e66a00d0144a83bb4e2a8210375a31.zip |
Move mutexes and condition from static memory allocation to dynamic
Add reference counting to glue
Change-Id: I2380d4cc4a761374b69f062a0906a1a388a26a2c
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
-rw-r--r-- | src/common/glib-glue.c | 162 | ||||
-rw-r--r-- | src/common/mainloop.c | 8 |
2 files changed, 108 insertions, 62 deletions
diff --git a/src/common/glib-glue.c b/src/common/glib-glue.c index 9bfcdf1..7cd469f 100644 --- a/src/common/glib-glue.c +++ b/src/common/glib-glue.c @@ -37,14 +37,14 @@ #define MURPHY_LOOP_WAIT_TIME_THREAD 1 -static GMutex g_murphy_glue_callback_lock; -static GMutex g_murphy_glue_internal_lock; -static GCond g_murphy_loop_cond; - typedef struct { GMainLoop *gml; GThread *worker; + GMutex glue_callback_lock; + GMutex glue_internal_lock; + GCond loop_cond; + gint ref_count; } glib_glue_t; @@ -102,6 +102,43 @@ static guint add_timeout(void *glue_data, GSourceFunc cb, unsigned int msecs, vo static guint add_io_watch(void *glue_data, GSourceFunc cb, GIOCondition mask, GIOChannel *ioc, void *user_data); static void remove_source(void *glue_data, guint id); +static glib_glue_t* glue_new() +{ + glib_glue_t *glue = NULL; + glue = mrp_allocz(sizeof(*glue)); + if (NULL != glue) { + g_mutex_init(&glue->glue_callback_lock); + g_mutex_init(&glue->glue_internal_lock); + g_cond_init(&glue->loop_cond); + glue->ref_count = 1; + } + return glue; +} + +static glib_glue_t* glue_ref(glib_glue_t *glue) +{ + g_return_val_if_fail(glue != NULL, NULL); + g_return_val_if_fail(g_atomic_int_get(&glue->ref_count) > 0, NULL); + + g_atomic_int_inc(&glue->ref_count); + + return glue; +} + +static void glue_unref(glib_glue_t *glue) +{ + g_return_if_fail(glue != NULL); + g_return_if_fail(g_atomic_int_get(&glue->ref_count) > 0); + + if (!g_atomic_int_dec_and_test(&glue->ref_count)) + return; + + g_mutex_clear(&glue->glue_callback_lock); + g_mutex_clear(&glue->glue_internal_lock); + g_cond_clear(&glue->loop_cond); + mrp_free(glue); +} + static guint add_timeout(void *glue_data, GSourceFunc cb, unsigned int msecs, void *user_data) { guint id = 0; @@ -143,8 +180,10 @@ 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; + glib_glue_t *glue = (glib_glue_t *)io->glue_data; + glue_ref(glue); + g_mutex_lock(&glue->glue_callback_lock); mrp_io_event_t events = MRP_IO_EVENT_NONE; int fd = g_io_channel_unix_get_fd(ioc); @@ -159,7 +198,8 @@ 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); + g_mutex_unlock(&glue->glue_callback_lock); + glue_unref(glue); return TRUE; } @@ -172,12 +212,13 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events, GIOCondition mask = 0; GIOChannel *ioc; io_t *io; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); ioc = g_io_channel_unix_new(fd); if (ioc == NULL) { - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); return NULL; } @@ -199,7 +240,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); + g_mutex_unlock(&glue->glue_internal_lock); return io; } else { @@ -208,7 +249,7 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events, } } - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); return NULL; } @@ -216,12 +257,13 @@ static void *add_io(void *glue_data, int fd, mrp_io_event_t events, static void del_io(void *glue_data, void *id) { io_t *io = (io_t *)id; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->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); + g_mutex_unlock(&glue->glue_internal_lock); } @@ -231,17 +273,21 @@ static gboolean timer_cb(gpointer user_data) return FALSE; } - g_mutex_lock(&g_murphy_glue_callback_lock); tmr_t *t = (tmr_t *)user_data; + glib_glue_t *glue = (glib_glue_t *)t->glue_data; + glue_ref(glue); + g_mutex_lock(&glue->glue_callback_lock); if (t->cb == NULL) { - g_mutex_unlock(&g_murphy_glue_callback_lock); + g_mutex_unlock(&glue->glue_callback_lock); + glue_unref(glue); return FALSE; } t->cb(t->glue_data, t, t->user_data); - g_mutex_unlock(&g_murphy_glue_callback_lock); + g_mutex_unlock(&glue->glue_callback_lock); + glue_unref(glue); return TRUE; } @@ -251,8 +297,9 @@ static void *add_timer(void *glue_data, unsigned int msecs, void *user_data) { tmr_t *t; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); t = mrp_allocz(sizeof(*t)); if (t != NULL) { @@ -263,14 +310,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); + g_mutex_unlock(&glue->glue_internal_lock); return t; } else mrp_free(t); } - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); return NULL; } @@ -278,24 +325,26 @@ static void *add_timer(void *glue_data, unsigned int msecs, static void del_timer(void *glue_data, void *id) { tmr_t *t = (tmr_t *)id; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); remove_source(glue_data, t->gl_t); mrp_free(t); - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); } static void mod_timer(void *glue_data, void *id, unsigned int msecs) { tmr_t *t = (tmr_t *)id; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->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); + g_mutex_unlock(&glue->glue_internal_lock); } @@ -305,17 +354,21 @@ static gboolean defer_cb(void *user_data) return FALSE; } - g_mutex_lock(&g_murphy_glue_callback_lock); dfr_t *d = (dfr_t *)user_data; + glib_glue_t *glue = (glib_glue_t *)d->glue_data; + glue_ref(glue); + g_mutex_lock(&glue->glue_callback_lock); if (d->cb == NULL) { - g_mutex_unlock(&g_murphy_glue_callback_lock); + g_mutex_unlock(&glue->glue_callback_lock); + glue_unref(glue); return FALSE; } d->cb(d->glue_data, d, d->user_data); - g_mutex_unlock(&g_murphy_glue_callback_lock); + g_mutex_unlock(&glue->glue_callback_lock); + glue_unref(glue); return TRUE; } @@ -325,8 +378,9 @@ static void *add_defer(void *glue_data, void *user_data) { dfr_t *d; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); d = mrp_allocz(sizeof(*d)); if (d != NULL) { @@ -337,14 +391,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); + g_mutex_unlock(&glue->glue_internal_lock); return d; } else mrp_free(d); } - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); return NULL; } @@ -352,25 +406,27 @@ static void *add_defer(void *glue_data, static void del_defer(void *glue_data, void *id) { dfr_t *d = (dfr_t *)id; + glib_glue_t *glue = (glib_glue_t *)glue_data; - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->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); + g_mutex_unlock(&glue->glue_internal_lock); } static void mod_defer(void *glue_data, void *id, int enabled) { dfr_t *d = (dfr_t *)id; + glib_glue_t *glue = (glib_glue_t *)glue_data; if (d == NULL) { return; } - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); if (enabled && !d->gl_t) { d->gl_t = add_timeout(glue_data, (GSourceFunc)defer_cb, 0, d); } @@ -378,7 +434,7 @@ 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); + g_mutex_unlock(&glue->glue_internal_lock); } @@ -387,7 +443,7 @@ 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); - g_mutex_lock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); if (loop_ctx && def_ctx != loop_ctx) { GSource *idle = g_idle_source_new(); gint64 end_time = 0; @@ -398,7 +454,7 @@ static void unregister(void *data) g_source_attach(idle, g_main_loop_get_context(glue->gml)); g_source_unref(idle); end_time = g_get_monotonic_time() + MURPHY_LOOP_WAIT_TIME_THREAD * G_TIME_SPAN_SECOND; - if (g_cond_wait_until(&g_murphy_loop_cond, &g_murphy_glue_internal_lock, end_time)) { + if (g_cond_wait_until(&glue->loop_cond, &glue->glue_internal_lock, end_time)) { g_thread_join(glue->worker); glue->worker = NULL; } @@ -409,8 +465,8 @@ static void unregister(void *data) glue->gml = NULL; } - mrp_free(glue); - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_unlock(&glue->glue_internal_lock); + glue_unref(glue); } @@ -439,9 +495,9 @@ thread_main (gpointer data) g_main_context_pop_thread_default (thread_main_context); - g_mutex_lock(&g_murphy_glue_internal_lock); - g_cond_signal(&g_murphy_loop_cond); - g_mutex_unlock(&g_murphy_glue_internal_lock); + g_mutex_lock(&glue->glue_internal_lock); + g_cond_signal(&glue->loop_cond); + g_mutex_unlock(&glue->glue_internal_lock); return NULL; } @@ -450,7 +506,7 @@ int mrp_mainloop_register_with_glib(mrp_mainloop_t *ml, GMainLoop *gml) { glib_glue_t *glue; - glue = mrp_allocz(sizeof(*glue)); + glue = glue_new(); if (glue != NULL) { glue->gml = g_main_loop_ref(gml); @@ -463,17 +519,15 @@ int mrp_mainloop_register_with_glib(mrp_mainloop_t *ml, GMainLoop *gml) if (loop_ctx && def_ctx != loop_ctx) { glue->worker = g_thread_try_new(NULL, thread_main, glue, NULL); if (glue->worker == NULL) { - g_main_loop_unref(gml); - mrp_free(glue); + mrp_log_error("Thread creation failed"); return FALSE; } } return TRUE; } - else { - g_main_loop_unref(gml); - mrp_free(glue); - } + mrp_log_error("Failed to set operation to superloop"); + g_main_loop_unref(gml); + glue_unref(glue); } return FALSE; @@ -503,19 +557,3 @@ 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); - g_cond_init(&g_murphy_loop_cond); -} - - -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); - g_cond_clear(&g_murphy_loop_cond); -} diff --git a/src/common/mainloop.c b/src/common/mainloop.c index 6519c9d..cff4385 100644 --- a/src/common/mainloop.c +++ b/src/common/mainloop.c @@ -2043,7 +2043,9 @@ static void dispatch_wakeup(mrp_mainloop_t *ml) if (!is_deleted(w)) { mrp_debug("dispatching wakeup cb %p", w); + pthread_mutex_unlock(&ml->lock); wakeup_cb(w, event, now); + pthread_mutex_lock(&ml->lock); } else mrp_debug("skipping deleted wakeup cb %p", w); @@ -2064,7 +2066,9 @@ static void dispatch_deferred(mrp_mainloop_t *ml) if (!is_deleted(d) && !d->inactive) { mrp_debug("dispatching active deferred cb %p", d); + pthread_mutex_unlock(&ml->lock); d->cb(d, d->user_data); + pthread_mutex_lock(&ml->lock); } else mrp_debug("skipping %s deferred cb %p", @@ -2094,7 +2098,9 @@ static void dispatch_timers(mrp_mainloop_t *ml) if (t->expire <= now) { mrp_debug("dispatching expired timer %p", t); + pthread_mutex_unlock(&ml->lock); t->cb(t, t->user_data); + pthread_mutex_lock(&ml->lock); if (!is_deleted(t)) rearm_timer(t); @@ -2177,7 +2183,9 @@ static void dispatch_poll_events(mrp_mainloop_t *ml) if (!is_deleted(w)) { mrp_debug("dispatching I/O watch %p (fd %d)", w, fd); + pthread_mutex_unlock(&ml->lock); w->cb(w, w->fd, e->events, w->user_data); + pthread_mutex_lock(&ml->lock); } else mrp_debug("skipping deleted I/O watch %p (fd %d)", w, fd); |