Permalink
Browse files

Support per-thread and system-wide lock modes

A THREAD lock mode is used when another thread cannot access some shared state,
for instance when populating an in-memory cache.

A PROCESS lock mode is used when the package manager is doing something to the
system, which should be locked even for other processes.

This breaks API and ABI, again.
  • Loading branch information...
1 parent 819dc43 commit 1c082edd1ccf9fdd3552cb39726df2bc38716ad5 @hughsie committed Jun 14, 2012
View
@@ -60,6 +60,7 @@ struct _ZifConfigPrivate
GHashTable *hash_override;
GHashTable *hash_default;
gchar **basearch_list;
+ GMutex mutex;
};
G_DEFINE_TYPE (ZifConfig, zif_config, G_TYPE_OBJECT)
@@ -105,6 +106,9 @@ zif_config_load (ZifConfig *config,
GError *error_local = NULL;
guint config_schema_version;
+ /* lock other threads */
+ g_mutex_lock (&config->priv->mutex);
+
/* already loaded */
if (config->priv->loaded)
goto out;
@@ -170,6 +174,8 @@ zif_config_load (ZifConfig *config,
/* done */
config->priv->loaded = TRUE;
out:
+ /* unlock other threads */
+ g_mutex_unlock (&config->priv->mutex);
return ret;
}
View
@@ -138,16 +138,17 @@ zif_groups_set_mapping_file (ZifGroups *groups, const gchar *mapping_file, GErro
/**
* zif_groups_load:
* @groups: A #ZifGroups
+ * @state: A #ZifState to use for progress reporting
* @error: A #GError, or %NULL
*
* Loads the mapping file from disk into memory.
*
* Return value: %TRUE for success, %FALSE otherwise
*
- * Since: 0.1.0
+ * Since: 0.3.1
**/
gboolean
-zif_groups_load (ZifGroups *groups, GError **error)
+zif_groups_load (ZifGroups *groups, ZifState *state, GError **error)
{
gboolean ret = TRUE;
gchar *data = NULL;
@@ -165,6 +166,14 @@ zif_groups_load (ZifGroups *groups, GError **error)
if (groups->priv->loaded)
goto out;
+ /* take lock */
+ ret = zif_state_take_lock (state,
+ ZIF_LOCK_TYPE_GROUPS,
+ ZIF_LOCK_MODE_THREAD,
+ error);
+ if (!ret)
+ goto out;
+
/* no mapping file */
if (groups->priv->mapping_file == NULL) {
ret = FALSE;
@@ -216,17 +225,20 @@ zif_groups_load (ZifGroups *groups, GError **error)
/**
* zif_groups_get_groups:
* @groups: A #ZifGroups
+ * @state: A #ZifState to use for progress reporting
* @error: A #GError, or %NULL
*
* Gets the groups supported by the packaging system.
*
* Return value: (transfer full): An array of the string groups that are supported, free
* with g_ptr_array_unref() when done.
*
- * Since: 0.1.0
+ * Since: 0.3.1
**/
GPtrArray *
-zif_groups_get_groups (ZifGroups *groups, GError **error)
+zif_groups_get_groups (ZifGroups *groups,
+ ZifState *state,
+ GError **error)
{
GError *error_local = NULL;
gboolean ret;
@@ -236,7 +248,7 @@ zif_groups_get_groups (ZifGroups *groups, GError **error)
/* if not already loaded, load */
if (!groups->priv->loaded) {
- ret = zif_groups_load (groups, &error_local);
+ ret = zif_groups_load (groups, state, &error_local);
if (!ret) {
g_set_error (error, ZIF_GROUPS_ERROR, ZIF_GROUPS_ERROR_FAILED,
"failed to load config file: %s", error_local->message);
@@ -251,17 +263,20 @@ zif_groups_get_groups (ZifGroups *groups, GError **error)
/**
* zif_groups_get_categories:
* @groups: A #ZifGroups
+ * @state: A #ZifState to use for progress reporting
* @error: A #GError, or %NULL
*
* Gets the categories supported by the packaging system.
*
* Return value: (transfer full): An array of category list as strings, free
* with g_ptr_array_unref() when done.
*
- * Since: 0.1.0
+ * Since: 0.3.1
**/
GPtrArray *
-zif_groups_get_categories (ZifGroups *groups, GError **error)
+zif_groups_get_categories (ZifGroups *groups,
+ ZifState *state,
+ GError **error)
{
guint i;
GPtrArray *array = NULL;
@@ -273,7 +288,7 @@ zif_groups_get_categories (ZifGroups *groups, GError **error)
/* if not already loaded, load */
if (!groups->priv->loaded) {
- ret = zif_groups_load (groups, &error_local);
+ ret = zif_groups_load (groups, state, &error_local);
if (!ret) {
g_set_error (error, ZIF_GROUPS_ERROR, ZIF_GROUPS_ERROR_FAILED,
"failed to load config file: %s", error_local->message);
@@ -294,17 +309,21 @@ zif_groups_get_categories (ZifGroups *groups, GError **error)
* zif_groups_get_cats_for_group:
* @groups: A #ZifGroups
* @group_enum: A group enumeration, e.g. "education"
+ * @state: A #ZifState to use for progress reporting
* @error: A #GError, or %NULL
*
* Gets all the categories that map to to this group enumeration.
*
* Return value: (transfer full): An array of category list as strings, free
* with g_ptr_array_unref() when done.
*
- * Since: 0.1.1
+ * Since: 0.3.1
**/
GPtrArray *
-zif_groups_get_cats_for_group (ZifGroups *groups, const gchar *group_enum, GError **error)
+zif_groups_get_cats_for_group (ZifGroups *groups,
+ const gchar *group_enum,
+ ZifState *state,
+ GError **error)
{
guint i;
GPtrArray *array = NULL;
@@ -322,7 +341,7 @@ zif_groups_get_cats_for_group (ZifGroups *groups, const gchar *group_enum, GErro
/* if not already loaded, load */
if (!priv->loaded) {
- ret = zif_groups_load (groups, &error_local);
+ ret = zif_groups_load (groups, state, &error_local);
if (!ret) {
g_set_error (error, ZIF_GROUPS_ERROR, ZIF_GROUPS_ERROR_FAILED,
"failed to load config file: %s", error_local->message);
@@ -353,16 +372,20 @@ zif_groups_get_cats_for_group (ZifGroups *groups, const gchar *group_enum, GErro
* zif_groups_get_group_for_cat:
* @groups: A #ZifGroups
* @cat: Category name, e.g. "games/action"
+ * @state: A #ZifState to use for progress reporting
* @error: A #GError, or %NULL
*
* Returns the group enumerated type for the category.
*
* Return value: A specific group name or %NULL
*
- * Since: 0.1.0
+ * Since: 0.3.1
**/
const gchar *
-zif_groups_get_group_for_cat (ZifGroups *groups, const gchar *cat, GError **error)
+zif_groups_get_group_for_cat (ZifGroups *groups,
+ const gchar *cat,
+ ZifState *state,
+ GError **error)
{
const gchar *group = NULL;
GError *error_local = NULL;
@@ -374,7 +397,7 @@ zif_groups_get_group_for_cat (ZifGroups *groups, const gchar *cat, GError **erro
/* if not already loaded, load */
if (!groups->priv->loaded) {
- ret = zif_groups_load (groups, &error_local);
+ ret = zif_groups_load (groups, state, &error_local);
if (!ret) {
g_set_error (error, ZIF_GROUPS_ERROR, ZIF_GROUPS_ERROR_FAILED,
"failed to load config file: %s", error_local->message);
View
@@ -28,6 +28,8 @@
#include <glib-object.h>
+#include "zif-state.h"
+
G_BEGIN_DECLS
#define ZIF_TYPE_GROUPS (zif_groups_get_type ())
@@ -70,16 +72,21 @@ gboolean zif_groups_set_mapping_file (ZifGroups *groups,
const gchar *mapping_file,
GError **error);
gboolean zif_groups_load (ZifGroups *groups,
+ ZifState *state,
GError **error);
GPtrArray *zif_groups_get_groups (ZifGroups *groups,
+ ZifState *state,
GError **error);
GPtrArray *zif_groups_get_categories (ZifGroups *groups,
+ ZifState *state,
GError **error);
GPtrArray *zif_groups_get_cats_for_group (ZifGroups *groups,
const gchar *group_enum,
+ ZifState *state,
GError **error);
const gchar *zif_groups_get_group_for_cat (ZifGroups *groups,
const gchar *cat,
+ ZifState *state,
GError **error);
G_END_DECLS
View
@@ -80,18 +80,32 @@ zif_history_load (ZifHistory *history, GError **error)
gboolean ret = TRUE;
gchar *error_msg = NULL;
gint rc;
+ guint lock_id;
+ ZifLock *lock = NULL;
/* already loaded */
if (history->priv->loaded)
goto out;
+ /* take lock */
+ lock = zif_lock_new ();
+ lock_id = zif_lock_take (lock,
+ ZIF_LOCK_TYPE_HISTORY,
+ ZIF_LOCK_MODE_THREAD,
+ error);
+ if (lock_id == 0) {
+ ret = FALSE;
+ goto out;
+ }
+
/* nothing set */
if (history->priv->filename == NULL) {
history->priv->filename = zif_config_get_string (history->priv->config,
"history_db",
error);
if (history->priv->filename == NULL) {
ret = FALSE;
+ zif_lock_release_noerror (lock, lock_id);
goto out;
}
}
@@ -100,8 +114,10 @@ zif_history_load (ZifHistory *history, GError **error)
ret = zif_ensure_parent_dir_exists (history->priv->filename,
NULL,
error);
- if (!ret)
+ if (!ret) {
+ zif_lock_release_noerror (lock, lock_id);
goto out;
+ }
/* open db */
g_debug ("trying to open database '%s'", history->priv->filename);
@@ -116,6 +132,7 @@ zif_history_load (ZifHistory *history, GError **error)
sqlite3_errmsg (history->priv->db));
sqlite3_close (history->priv->db);
history->priv->db = NULL;
+ zif_lock_release_noerror (lock, lock_id);
goto out;
}
@@ -155,7 +172,16 @@ zif_history_load (ZifHistory *history, GError **error)
/* yippee */
history->priv->loaded = TRUE;
+
+ /* unlock */
+ ret = zif_lock_release (lock,
+ lock_id,
+ error);
+ if (!ret)
+ goto out;
out:
+ if (lock != NULL)
+ g_object_unref (lock);
return ret;
}
Oops, something went wrong.

0 comments on commit 1c082ed

Please sign in to comment.