[evolution-data-server/evolution-data-server-3-12] [EBookBackendGoogle] Guard private 'groups' members with a lock
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/evolution-data-server-3-12] [EBookBackendGoogle] Guard private 'groups' members with a lock
- Date: Thu, 22 May 2014 09:16:16 +0000 (UTC)
commit d1308feb1719e4a0eb056262f97c3a5ee078207a
Author: Milan Crha <mcrha redhat com>
Date: Thu May 22 11:04:53 2014 +0200
[EBookBackendGoogle] Guard private 'groups' members with a lock
The 'groups' related private member scan be read/write from multiple
threads simultaneously, thus guard them with a lock. Maybe it is
related to bug #725045, maybe not.
.../backends/google/e-book-backend-google.c | 65 +++++++++++++++++---
1 files changed, 55 insertions(+), 10 deletions(-)
---
diff --git a/addressbook/backends/google/e-book-backend-google.c
b/addressbook/backends/google/e-book-backend-google.c
index 0976aaf..0288883 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -62,6 +62,8 @@ struct _EBookBackendGooglePrivate {
EBookBackendCache *cache;
GMutex cache_lock;
+ /* For all the group-related members */
+ GRecMutex groups_lock;
/* Mapping from group ID to (human readable) group name */
GHashTable *groups_by_id;
/* Mapping from (human readable) group name to group ID */
@@ -71,7 +73,7 @@ struct _EBookBackendGooglePrivate {
/* Mapping entry ID to system_group_id */
GHashTable *system_groups_by_entry_id;
/* Time when the groups were last queried */
- GTimeVal last_groups_update;
+ GTimeVal groups_last_update;
GDataAuthorizer *authorizer;
GDataService *service;
@@ -246,7 +248,10 @@ cache_add_contact (EBookBackend *backend,
priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
+ g_rec_mutex_lock (&priv->groups_lock);
contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
+ g_rec_mutex_unlock (&priv->groups_lock);
+
e_contact_add_gdata_entry_xml (contact, entry);
g_mutex_lock (&priv->cache_lock);
e_book_backend_cache_add_contact (priv->cache, contact);
@@ -887,6 +892,8 @@ process_group (GDataEntry *entry,
system_group_id = gdata_contacts_group_get_system_group_id (GDATA_CONTACTS_GROUP (entry));
is_deleted = gdata_contacts_group_is_deleted (GDATA_CONTACTS_GROUP (entry));
+ g_rec_mutex_lock (&priv->groups_lock);
+
if (system_group_id) {
g_debug ("Processing %ssystem group %s, %s", is_deleted ? "(deleted) " : "", system_group_id,
uid);
@@ -928,6 +935,8 @@ process_group (GDataEntry *entry,
priv->groups_changed = cache_update_group (backend, uid, name) || priv->groups_changed;
}
+ g_rec_mutex_unlock (&priv->groups_lock);
+
g_free (name);
}
@@ -954,17 +963,25 @@ get_groups_cb (GDataService *service,
if (!gdata_error) {
/* Update the update time */
- g_get_current_time (&(priv->last_groups_update));
+ g_rec_mutex_lock (&priv->groups_lock);
+ g_get_current_time (&(priv->groups_last_update));
+ g_rec_mutex_unlock (&priv->groups_lock);
}
finish_operation (backend, -2, gdata_error);
+ g_rec_mutex_lock (&priv->groups_lock);
+
if (priv->groups_changed) {
priv->groups_changed = FALSE;
+ g_rec_mutex_unlock (&priv->groups_lock);
+
/* do the update for all contacts, like with an empty cache */
cache_set_last_update (backend, NULL);
get_new_contacts (backend);
+ } else {
+ g_rec_mutex_unlock (&priv->groups_lock);
}
g_object_unref (backend);
@@ -984,17 +1001,21 @@ get_groups (EBookBackend *backend)
g_debug (G_STRFUNC);
g_return_if_fail (backend_is_authorized (backend));
+ g_rec_mutex_lock (&priv->groups_lock);
+
/* Build our query */
query = GDATA_QUERY (gdata_contacts_query_new_with_limits (NULL, 0, G_MAXINT));
- if (priv->last_groups_update.tv_sec != 0 || priv->last_groups_update.tv_usec != 0) {
- gdata_query_set_updated_min (query, priv->last_groups_update.tv_sec);
+ if (priv->groups_last_update.tv_sec != 0 || priv->groups_last_update.tv_usec != 0) {
+ gdata_query_set_updated_min (query, priv->groups_last_update.tv_sec);
gdata_contacts_query_set_show_deleted (GDATA_CONTACTS_QUERY (query), TRUE);
}
- g_object_ref (backend);
-
priv->groups_changed = FALSE;
+ g_rec_mutex_unlock (&priv->groups_lock);
+
+ g_object_ref (backend);
+
/* Run the query asynchronously */
cancellable = start_operation (backend, -2, NULL, _("Querying for updated groups…"));
gdata_contacts_service_query_groups_async (
@@ -1056,11 +1077,15 @@ create_group (EBookBackend *backend,
system_group_id = e_contact_map_google_with_evo_group (category_name, FALSE);
if (system_group_id) {
- const gchar *group_entry_id = g_hash_table_lookup (priv->system_groups_by_id,
system_group_id);
+ gchar *group_entry_id;
+
+ g_rec_mutex_lock (&priv->groups_lock);
+ group_entry_id = g_strdup (g_hash_table_lookup (priv->system_groups_by_id, system_group_id));
+ g_rec_mutex_unlock (&priv->groups_lock);
g_return_val_if_fail (group_entry_id != NULL, NULL);
- return g_strdup (group_entry_id);
+ return group_entry_id;
}
group = GDATA_ENTRY (gdata_contacts_group_new (NULL));
@@ -1081,8 +1106,12 @@ create_group (EBookBackend *backend,
/* Add the new group to the group mappings */
uid = g_strdup (gdata_entry_get_id (new_group));
+
+ g_rec_mutex_lock (&priv->groups_lock);
g_hash_table_replace (priv->groups_by_id, e_contact_sanitise_google_group_id (uid), g_strdup
(category_name));
g_hash_table_replace (priv->groups_by_name, g_strdup (category_name),
e_contact_sanitise_google_group_id (uid));
+ g_rec_mutex_unlock (&priv->groups_lock);
+
g_object_unref (new_group);
/* Update the cache. */
@@ -1140,8 +1169,14 @@ cache_refresh_if_needed (EBookBackend *backend)
refresh_local_cache_cb,
backend,
NULL);
- } else if (g_hash_table_size (priv->system_groups_by_id) == 0) {
- get_groups (backend);
+ } else {
+ g_rec_mutex_lock (&priv->groups_lock);
+ if (g_hash_table_size (priv->system_groups_by_id) == 0) {
+ g_rec_mutex_unlock (&priv->groups_lock);
+ get_groups (backend);
+ } else {
+ g_rec_mutex_unlock (&priv->groups_lock);
+ }
}
return;
@@ -1470,6 +1505,7 @@ book_backend_google_finalize (GObject *object)
}
g_mutex_clear (&priv->cache_lock);
+ g_rec_mutex_clear (&priv->groups_lock);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_book_backend_google_parent_class)->finalize (object);
@@ -1735,6 +1771,8 @@ book_backend_google_create_contacts_sync (EBookBackend *backend,
g_warn_if_fail (backend_is_authorized (backend));
+ g_rec_mutex_lock (&priv->groups_lock);
+
/* Ensure the system groups have been fetched. */
if (g_hash_table_size (priv->system_groups_by_id) == 0)
get_groups_sync (backend, cancellable);
@@ -1748,6 +1786,8 @@ book_backend_google_create_contacts_sync (EBookBackend *backend,
_create_group, backend);
g_object_unref (contact);
+ g_rec_mutex_unlock (&priv->groups_lock);
+
/* Debug XML output */
xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
g_debug ("new entry with xml: %s", xml);
@@ -1902,6 +1942,8 @@ book_backend_google_modify_contacts_sync (EBookBackend *backend,
return FALSE;
}
+ g_rec_mutex_lock (&priv->groups_lock);
+
/* Ensure the system groups have been fetched. */
if (g_hash_table_size (priv->system_groups_by_id) == 0)
get_groups_sync (backend, cancellable);
@@ -1913,6 +1955,8 @@ book_backend_google_modify_contacts_sync (EBookBackend *backend,
priv->system_groups_by_id,
_create_group, backend);
+ g_rec_mutex_unlock (&priv->groups_lock);
+
/* Output debug XML */
xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
g_debug ("Before:\n%s", xml);
@@ -2344,6 +2388,7 @@ e_book_backend_google_init (EBookBackendGoogle *backend)
backend->priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
g_mutex_init (&backend->priv->cache_lock);
+ g_rec_mutex_init (&backend->priv->groups_lock);
g_signal_connect (
backend, "notify::online",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]