summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolodymyr Brynza <v.brynza@samsung.com>2017-05-12 14:33:52 +0300
committerVolodymyr Brynza <v.brynza@samsung.com>2017-05-12 14:33:52 +0300
commite25ee486b2e66a00d0144a83bb4e2a8210375a31 (patch)
treef18df3bae7cd10c5a757b2554d84e24601990a1c
parent2c8263babf1f094e8dfe8b17bf0864e301e41571 (diff)
downloadmurphy-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.c162
-rw-r--r--src/common/mainloop.c8
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);