[evolution-data-server] Rationalise fragmented locking. Use a recursive lock everywhere in case of problems. Unify get_delta
- From: Michael Meeks <michael src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Rationalise fragmented locking. Use a recursive lock everywhere in case of problems. Unify get_delta
- Date: Thu, 4 Mar 2010 17:11:35 +0000 (UTC)
commit c59761e781ae3703d74649cfb2b7e9946946daf0
Author: Michael Meeks <michael meeks novell com>
Date: Thu Mar 4 17:10:59 2010 +0000
Rationalise fragmented locking.
Use a recursive lock everywhere in case of problems.
Unify get_deltas lock with the main connection lock, yet drop it for
the high latency get_objects call.
Fix memory corruption issue bgo#611815
.../backends/groupwise/e-cal-backend-groupwise.c | 129 ++++++++++----------
1 files changed, 67 insertions(+), 62 deletions(-)
---
diff --git a/calendar/backends/groupwise/e-cal-backend-groupwise.c b/calendar/backends/groupwise/e-cal-backend-groupwise.c
index af50306..6b3169d 100644
--- a/calendar/backends/groupwise/e-cal-backend-groupwise.c
+++ b/calendar/backends/groupwise/e-cal-backend-groupwise.c
@@ -72,7 +72,7 @@ typedef struct {
/* Private part of the CalBackendGroupwise structure */
struct _ECalBackendGroupwisePrivate {
/* A mutex to control access to the private structure */
- GMutex *mutex;
+ GStaticRecMutex rec_mutex;
EGwConnection *cnc;
ECalBackendStore *store;
gboolean read_only;
@@ -101,6 +101,9 @@ struct _ECalBackendGroupwisePrivate {
SyncDelta *dlock;
};
+#define PRIV_LOCK(p) (g_static_rec_mutex_lock (&(p)->rec_mutex))
+#define PRIV_UNLOCK(p) (g_static_rec_mutex_unlock (&(p)->rec_mutex))
+
static void e_cal_backend_groupwise_dispose (GObject *object);
static void e_cal_backend_groupwise_finalize (GObject *object);
static void sanitize_component (ECalBackendSync *backend, ECalComponent *comp, gchar *server_uid);
@@ -152,8 +155,6 @@ e_cal_backend_groupwise_get_default_zone (ECalBackendGroupwise *cbgw) {
return cbgw->priv->default_zone;
}
-static GMutex *mutex = NULL;
-
static const gchar *
get_element_type (icalcomponent_kind kind)
{
@@ -197,11 +198,7 @@ populate_cache (ECalBackendGroupwise *cbgw)
kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbgw));
total = priv->total_count;
- if (!mutex) {
- mutex = g_mutex_new ();
- }
-
- g_mutex_lock (mutex);
+ PRIV_LOCK (priv);
type = get_element_type (kind);
@@ -239,7 +236,7 @@ populate_cache (ECalBackendGroupwise *cbgw)
"recipients message recipientStatus attachments default peek", filter[i], &cursor);
if (status != E_GW_CONNECTION_STATUS_OK) {
e_cal_backend_groupwise_notify_error_code (cbgw, status);
- g_mutex_unlock (mutex);
+ PRIV_UNLOCK (priv);
return status;
}
done = FALSE;
@@ -259,7 +256,7 @@ populate_cache (ECalBackendGroupwise *cbgw)
status = e_gw_connection_read_cursor (priv->cnc, priv->container_id, cursor, forward, CURSOR_ITEM_LIMIT, position, &list);
if (status != E_GW_CONNECTION_STATUS_OK) {
e_cal_backend_groupwise_notify_error_code (cbgw, status);
- g_mutex_unlock (mutex);
+ PRIV_UNLOCK (priv);
return status;
}
for (l = list; l != NULL; l = g_list_next(l)) {
@@ -307,7 +304,7 @@ populate_cache (ECalBackendGroupwise *cbgw)
}
e_cal_backend_notify_view_progress (E_CAL_BACKEND (cbgw), "", 100);
- g_mutex_unlock (mutex);
+ PRIV_UNLOCK (priv);
return E_GW_CONNECTION_STATUS_OK;
}
@@ -331,6 +328,8 @@ compare_ids (gconstpointer a, gconstpointer b)
return 1;
}
+#define ATTEMPTS_KEY "attempts"
+
static gboolean
get_deltas (gpointer handle)
{
@@ -345,10 +344,9 @@ get_deltas (gpointer handle)
GPtrArray *uid_array = NULL;
gchar *time_string = NULL;
gchar t_str [26];
+ gchar *attempts;
+ gchar *container_id;
const gchar *serv_time;
- static GStaticMutex connecting = G_STATIC_MUTEX_INIT;
- const gchar *key = "attempts";
- const gchar *attempts;
const gchar *position;
EGwFilter *filter;
@@ -362,19 +360,21 @@ get_deltas (gpointer handle)
if (!handle)
return FALSE;
+
cbgw = (ECalBackendGroupwise *) handle;
- priv= cbgw->priv;
+ priv = cbgw->priv;
+ if (priv->mode == CAL_MODE_LOCAL)
+ return FALSE;
+
+ PRIV_LOCK (priv);
+
kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbgw));
cnc = priv->cnc;
+
store = priv->store;
item_list = NULL;
- if (priv->mode == CAL_MODE_LOCAL)
- return FALSE;
-
- attempts = e_cal_backend_store_get_key_value (store, key);
-
- g_static_mutex_lock (&connecting);
+ attempts = g_strdup (e_cal_backend_store_get_key_value (store, ATTEMPTS_KEY));
serv_time = e_cal_backend_store_get_key_value (store, SERVER_UTC_TIME);
if (serv_time) {
@@ -405,31 +405,39 @@ get_deltas (gpointer handle)
e_gw_filter_add_filter_component (filter, E_GW_FILTER_OP_EQUAL, "@type", get_element_type (kind));
e_gw_filter_group_conditions (filter, E_GW_FILTER_OP_AND, 2);
- status = e_gw_connection_get_items (cnc, cbgw->priv->container_id, "attachments recipients message recipientStatus default peek", filter, &item_list);
+ container_id = g_strdup (cbgw->priv->container_id);
+ PRIV_UNLOCK (priv);
+
+ status = e_gw_connection_get_items (cnc, container_id, "attachments recipients message recipientStatus default peek", filter, &item_list);
if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
- status = e_gw_connection_get_items (cnc, cbgw->priv->container_id, "attachments recipients message recipientStatus default peek", filter, &item_list);
+ status = e_gw_connection_get_items (cnc, container_id, "attachments recipients message recipientStatus default peek", filter, &item_list);
+ PRIV_LOCK (priv);
+
+ g_free (container_id);
g_object_unref (filter);
if (status != E_GW_CONNECTION_STATUS_OK) {
const gchar *msg = NULL;
+ gint failures;
- if (!attempts) {
- e_cal_backend_store_put_key_value (store, key, "2");
- } else {
- gint failures;
- failures = g_ascii_strtod(attempts, NULL) + 1;
- e_cal_backend_store_put_key_value (store, key, GINT_TO_POINTER (failures));
- }
+ if (!attempts)
+ failures = 2;
+ else
+ failures = g_ascii_strtod (attempts, NULL) + 1;
+ g_free (attempts);
+ attempts = g_strdup_printf ("%d", failures);
+ e_cal_backend_store_put_key_value (store, ATTEMPTS_KEY, attempts);
+ g_free (attempts);
if (status == E_GW_CONNECTION_STATUS_NO_RESPONSE) {
- g_static_mutex_unlock (&connecting);
+ PRIV_UNLOCK (priv);
return TRUE;
}
msg = e_gw_connection_get_error_message (status);
- g_static_mutex_unlock (&connecting);
+ PRIV_UNLOCK (priv);
return TRUE;
}
@@ -501,10 +509,11 @@ get_deltas (gpointer handle)
if (attempts) {
tm.tm_min += (time_interval * g_ascii_strtod (attempts, NULL));
- e_cal_backend_store_put_key_value (store, key, NULL);
+ e_cal_backend_store_put_key_value (store, ATTEMPTS_KEY, NULL);
} else {
tm.tm_min += time_interval;
}
+ g_free (attempts);
strftime (t_str, 26, "%Y-%m-%dT%H:%M:%SZ", &tm);
time_string = g_strdup (t_str);
@@ -530,12 +539,12 @@ get_deltas (gpointer handle)
if (status != E_GW_CONNECTION_STATUS_OK) {
if (status == E_GW_CONNECTION_STATUS_NO_RESPONSE) {
- g_static_mutex_unlock (&connecting);
+ PRIV_UNLOCK (priv);
return TRUE;
}
e_cal_backend_groupwise_notify_error_code (cbgw, status);
- g_static_mutex_unlock (&connecting);
+ PRIV_UNLOCK (priv);
return TRUE;
}
@@ -679,7 +688,7 @@ get_deltas (gpointer handle)
g_slist_free (cache_ids);
}
- g_static_mutex_unlock (&connecting);
+ PRIV_UNLOCK (priv);
return TRUE;
}
@@ -791,9 +800,9 @@ e_cal_backend_groupwise_refresh_calendar (ECalBackendGroupwise *cbgw)
if (priv->mode == CAL_MODE_LOCAL)
return;
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
delta_started = fetch_deltas (cbgw);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
/* Emit the signal if the delta is already running */
if (!delta_started)
@@ -892,9 +901,9 @@ cache_init (ECalBackendGroupwise *cbgw)
}
}
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
fetch_deltas (cbgw);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return NULL;
}
@@ -1077,7 +1086,6 @@ connect_to_server (ECalBackendGroupwise *cbgw)
e_cal_backend_cache_remove (uri, source_type);
priv->store = (ECalBackendStore *) e_cal_backend_file_store_new (uri, source_type);
if (!priv->store) {
- g_mutex_unlock (priv->mutex);
e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Could not create cache file"));
return GNOME_Evolution_Calendar_OtherError;
}
@@ -1156,10 +1164,7 @@ e_cal_backend_groupwise_finalize (GObject *object)
priv->dthread = NULL;
}
- if (priv->mutex) {
- g_mutex_free (priv->mutex);
- priv->mutex = NULL;
- }
+ g_static_rec_mutex_free (&priv->rec_mutex);
if (priv->cnc) {
g_object_unref (priv->cnc);
@@ -1337,7 +1342,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, gboolean
cbgw = E_CAL_BACKEND_GROUPWISE (backend);
priv = cbgw->priv;
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
cbgw->priv->read_only = FALSE;
@@ -1367,7 +1372,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, gboolean
display_contents = e_source_get_property (esource, "offline_sync");
if (!display_contents || !g_str_equal (display_contents, "1")) {
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return GNOME_Evolution_Calendar_RepositoryOffline;
}
@@ -1378,7 +1383,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, gboolean
e_cal_backend_cache_remove (uri, source_type);
priv->store = (ECalBackendStore *) e_cal_backend_file_store_new (uri, source_type);
if (!priv->store) {
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Could not create cache file"));
return GNOME_Evolution_Calendar_OtherError;
@@ -1387,7 +1392,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, gboolean
e_cal_backend_store_set_default_timezone (priv->store, priv->default_zone);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return GNOME_Evolution_Calendar_Success;
}
@@ -1420,7 +1425,7 @@ e_cal_backend_groupwise_open (ECalBackendSync *backend, EDataCal *cal, gboolean
/* FIXME: no need to set it online here when we implement the online/offline stuff correctly */
status = connect_to_server (cbgw);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return status;
}
@@ -1433,13 +1438,13 @@ e_cal_backend_groupwise_remove (ECalBackendSync *backend, EDataCal *cal)
cbgw = E_CAL_BACKEND_GROUPWISE (backend);
priv = cbgw->priv;
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
/* remove the cache */
if (priv->store)
e_cal_backend_store_remove (priv->store);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return GNOME_Evolution_Calendar_Success;
}
@@ -1486,7 +1491,7 @@ e_cal_backend_groupwise_set_mode (ECalBackend *backend, CalMode mode)
return;
}
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
priv->mode_changed = TRUE;
switch (mode) {
@@ -1514,7 +1519,7 @@ e_cal_backend_groupwise_set_mode (ECalBackend *backend, CalMode mode)
cal_mode_to_corba (mode));
}
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
}
static ECalBackendSyncStatus
@@ -1555,12 +1560,12 @@ e_cal_backend_groupwise_get_object (ECalBackendSync *backend, EDataCal *cal, con
priv = cbgw->priv;
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
/* search the object in the cache */
comp = e_cal_backend_store_get_component (priv->store, uid, rid);
if (comp) {
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
if (e_cal_backend_get_kind (E_CAL_BACKEND (backend)) ==
icalcomponent_isa (e_cal_component_get_icalcomponent (comp)))
*object = e_cal_component_get_as_string (comp);
@@ -1572,7 +1577,7 @@ e_cal_backend_groupwise_get_object (ECalBackendSync *backend, EDataCal *cal, con
return *object ? GNOME_Evolution_Calendar_Success : GNOME_Evolution_Calendar_ObjectNotFound;
}
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
/* callers will never have a uuid that is in server but not in cache */
return GNOME_Evolution_Calendar_ObjectNotFound;
@@ -1663,7 +1668,7 @@ e_cal_backend_groupwise_get_object_list (ECalBackendSync *backend, EDataCal *cal
cbgw = E_CAL_BACKEND_GROUPWISE (backend);
priv = cbgw->priv;
- g_mutex_lock (priv->mutex);
+ PRIV_LOCK (priv);
g_message (G_STRLOC ": Getting object list (%s)", sexp);
@@ -1672,7 +1677,7 @@ e_cal_backend_groupwise_get_object_list (ECalBackendSync *backend, EDataCal *cal
cbsexp = e_cal_backend_sexp_new (sexp);
if (!cbsexp) {
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return GNOME_Evolution_Calendar_InvalidQuery;
}
@@ -1694,7 +1699,7 @@ e_cal_backend_groupwise_get_object_list (ECalBackendSync *backend, EDataCal *cal
g_slist_foreach (components, (GFunc) g_object_unref, NULL);
g_slist_free (components);
- g_mutex_unlock (priv->mutex);
+ PRIV_UNLOCK (priv);
return GNOME_Evolution_Calendar_Success;
}
@@ -1889,7 +1894,7 @@ e_cal_backend_groupwise_internal_get_default_timezone (ECalBackend *backend)
static icaltimezone *
e_cal_backend_groupwise_internal_get_timezone (ECalBackend *backend, const gchar *tzid)
{
- icaltimezone *zone;
+ icaltimezone *zone = NULL;
ECalBackendGroupwise *cbgw;
cbgw = E_CAL_BACKEND_GROUPWISE (backend);
@@ -2813,7 +2818,7 @@ e_cal_backend_groupwise_init (ECalBackendGroupwise *cbgw)
priv->sendoptions_sync_timeout = 0;
/* create the mutex for thread safety */
- priv->mutex = g_mutex_new ();
+ g_static_rec_mutex_init (&priv->rec_mutex);
cbgw->priv = priv;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]