coil_expand(gpointer object, const GValue **value_ptr, gboolean recursive, GError **error) { g_return_val_if_fail(COIL_IS_EXPANDABLE(object), FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); CoilExpandable *self = COIL_EXPANDABLE(object); CoilExpandablePrivate *const priv = self->priv; CoilExpandableClass *klass = COIL_EXPANDABLE_GET_CLASS(self); const GValue *return_value = NULL; GError *internal_error = NULL; /* TODO(jcon): notify container of expansion */ if (!g_static_mutex_trylock(&priv->expand_lock)) { /* TODO(jcon): improve error handling for cases like this */ coil_struct_error(&internal_error, COIL_IS_STRUCT(self) ? COIL_STRUCT(self) : self->container, "Cycle detected during expansion"); goto error; } if (!klass->expand(self, &return_value, error)) goto error; if (recursive && return_value /* want to expand return value */ && (value_ptr == NULL /* caller doesnt care about return value */ || return_value != *value_ptr) /* prevent expand cycle on same value */ && G_VALUE_HOLDS(return_value, COIL_TYPE_EXPANDABLE) /* must be expandable */ && !coil_expand_value(return_value, &return_value, TRUE, error)) goto error; g_static_mutex_unlock(&priv->expand_lock); if (value_ptr && return_value) *value_ptr = return_value; return TRUE; error: if (value_ptr) *value_ptr = NULL; if (internal_error) g_propagate_error(error, internal_error); g_static_mutex_unlock(&priv->expand_lock); return FALSE; }
void mbb_stat_pool_save(struct mbb_stat_pool *pool) { static GStaticMutex mutex = G_STATIC_MUTEX_INIT; mbb_log_lvl_t mask; mbb_log_mask(LOG_MASK_DEL, MBB_LOG_QUERY, &mask); if (! g_static_mutex_trylock(&mutex)) { mbb_log("wait for mutex"); g_static_mutex_lock(&mutex); } if (! mbb_task_poll_state()) goto out; mbb_log("save to db"); if (! db_begin()) goto out; if (! save_records(pool->ustat, unit_rec_save)) goto rollback; if (! save_records(pool->lstat, link_rec_save)) goto rollback; if (! save_records(pool->ulstat, unit_link_rec_save)) goto rollback; db_commit(); goto out; rollback: db_rollback(); out: mbb_log_mask(LOG_MASK_SET, mask, NULL); g_static_mutex_unlock(&mutex); mbb_stat_pool_free(pool); }
/* --------------------------- * gap_base_gimp_mutex_trylock * --------------------------- * lock the static gimpMutex singleton if present (e.g. is NOT NULL) * * return immediate FALSE in case the mutex is locked by another thread * return TRUE in case the mutex was locked successfully (may sleep until other threads unlock the mutex) * TRUE will be immediatly returned in case * the thread system is not initialized, e.g g_thread_init was not yet called */ gboolean gap_base_gimp_mutex_trylock(GapTimmRecord *gimpMutexStats) { gboolean isSuccessful; GStaticMutex *gimpMutex; gimpMutex = gap_base_get_gimp_mutex(); if(gimpMutex) { GAP_TIMM_START_RECORD(gimpMutexStats); isSuccessful = g_static_mutex_trylock (gimpMutex); GAP_TIMM_STOP_RECORD(gimpMutexStats); } else { isSuccessful = TRUE; } return(isSuccessful); } /* end gap_base_gimp_mutex_trylock */