evolution-data-server r8695 - in trunk/servers/exchange: . storage
- From: mcrha svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r8695 - in trunk/servers/exchange: . storage
- Date: Tue, 29 Apr 2008 08:51:02 +0100 (BST)
Author: mcrha
Date: Tue Apr 29 07:51:02 2008
New Revision: 8695
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8695&view=rev
Log:
2008-04-29 Milan Crha <mcrha redhat com>
** Fix for bug #502899
* storage/exchange-account.c: (struct _ExchangeAccountPrivate), (init),
(dispose), (finalize), (exchange_account_rescan_tree), (get_folder),
(hierarchy_new_folder), (hierarchy_removed_folder), (context_redirect),
(get_parent_and_name), (exchange_account_get_folder),
(exchange_account_get_folders), (exchange_account_get_folder_tree):
Guard private folder's hash tables with a lock to prevent access to
them from different threads in same the time.
Modified:
trunk/servers/exchange/ChangeLog
trunk/servers/exchange/storage/exchange-account.c
Modified: trunk/servers/exchange/storage/exchange-account.c
==============================================================================
--- trunk/servers/exchange/storage/exchange-account.c (original)
+++ trunk/servers/exchange/storage/exchange-account.c Tue Apr 29 07:51:02 2008
@@ -71,6 +71,7 @@
GHashTable *hierarchies_by_folder, *foreign_hierarchies;
ExchangeHierarchy *favorites_hierarchy;
GHashTable *folders, *fresh_folders;
+ GStaticRecMutex folders_lock;
char *uri_authority, *http_uri_schema;
gboolean uris_use_email, offline_sync;
@@ -154,6 +155,7 @@
account->priv->foreign_hierarchies = g_hash_table_new (g_str_hash, g_str_equal);
account->priv->folders = g_hash_table_new (g_str_hash, g_str_equal);
account->priv->fresh_folders = NULL;
+ g_static_rec_mutex_init (&account->priv->folders_lock);
account->priv->discover_data_lock = g_mutex_new ();
account->priv->account_online = UNSUPPORTED_MODE;
account->priv->nt_domain = NULL;
@@ -205,17 +207,19 @@
account->priv->hierarchies = NULL;
}
- if (account->priv->hierarchies_by_folder) {
- g_hash_table_destroy (account->priv->hierarchies_by_folder);
- account->priv->hierarchies_by_folder = NULL;
- }
-
if (account->priv->foreign_hierarchies) {
g_hash_table_foreach (account->priv->foreign_hierarchies, free_name, NULL);
g_hash_table_destroy (account->priv->foreign_hierarchies);
account->priv->foreign_hierarchies = NULL;
}
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
+
+ if (account->priv->hierarchies_by_folder) {
+ g_hash_table_destroy (account->priv->hierarchies_by_folder);
+ account->priv->hierarchies_by_folder = NULL;
+ }
+
if (account->priv->folders) {
g_hash_table_foreach (account->priv->folders, free_folder, NULL);
g_hash_table_destroy (account->priv->folders);
@@ -228,6 +232,8 @@
account->priv->fresh_folders = NULL;
}
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -303,6 +309,8 @@
if (account->priv->discover_data_lock)
g_mutex_free (account->priv->discover_data_lock);
+ g_static_rec_mutex_free (&account->priv->folders_lock);
+
g_free (account->priv);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -320,6 +328,7 @@
g_return_if_fail (EXCHANGE_IS_ACCOUNT (account));
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
if (account->priv->fresh_folders) {
g_hash_table_foreach (account->priv->fresh_folders, free_folder, NULL);
g_hash_table_destroy (account->priv->fresh_folders);
@@ -339,6 +348,7 @@
toplevel, account->priv->account_online);
exchange_hierarchy_rescan (account->priv->hierarchies->pdata[i]);
}
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
}
/*
@@ -354,6 +364,8 @@
e_folder_exchange_get_permanent_uri (folder);
char *key;
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
+
/* This makes the cleanup easier. We just unref it each time
* we find it in account->priv->folders.
*/
@@ -411,8 +423,11 @@
{
g_hash_table_insert (account->priv->hierarchies_by_folder,
folder, hier);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
g_signal_emit (account, signals[NEW_FOLDER], 0, folder);
+ } else {
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
}
}
@@ -420,9 +435,12 @@
hierarchy_removed_folder (ExchangeHierarchy *hier, EFolder *folder,
ExchangeAccount *account)
{
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
if (!g_hash_table_lookup (account->priv->folders,
- e_folder_exchange_get_path (folder)))
+ e_folder_exchange_get_path (folder))) {
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
return;
+ }
g_hash_table_remove (account->priv->folders,
e_folder_exchange_get_path (folder));
@@ -435,6 +453,7 @@
e_folder_exchange_get_internal_uri (folder));
}
g_hash_table_remove (account->priv->hierarchies_by_folder, folder);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
g_signal_emit (account, signals[REMOVED_FOLDER], 0, folder);
if (folder == hier->toplevel)
@@ -451,11 +470,15 @@
get_folder (ExchangeAccount *account, const char *path,
EFolder **folder, ExchangeHierarchy **hier)
{
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
*folder = g_hash_table_lookup (account->priv->folders, path);
- if (!*folder)
+ if (!*folder) {
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
return FALSE;
+ }
*hier = g_hash_table_lookup (account->priv->hierarchies_by_folder,
*folder);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
if (!*hier)
return FALSE;
return TRUE;
@@ -471,15 +494,19 @@
if (!name)
return FALSE;
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
parent_path = g_strndup (*path, name - *path);
*parent = g_hash_table_lookup (account->priv->folders, parent_path);
g_free (parent_path);
- if (!*parent)
+ if (!*parent) {
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
return FALSE;
+ }
*hier = g_hash_table_lookup (account->priv->hierarchies_by_folder,
*parent);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
if (!*hier)
return FALSE;
@@ -845,15 +872,20 @@
{
EFolder *folder;
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
folder = g_hash_table_lookup (account->priv->folders, old_uri);
- if (!folder)
+ if (!folder) {
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
return;
+ }
g_hash_table_remove (account->priv->folders, old_uri);
e_folder_exchange_set_internal_uri (folder, new_uri);
g_hash_table_insert (account->priv->folders,
(char *)e_folder_exchange_get_internal_uri (folder),
folder);
+
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
}
static void
@@ -1858,11 +1890,17 @@
exchange_account_get_folder (ExchangeAccount *account,
const char *path_or_uri)
{
+ EFolder *folder;
+
g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
if (!path_or_uri)
return NULL;
- return g_hash_table_lookup (account->priv->folders, path_or_uri);
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
+ folder = g_hash_table_lookup (account->priv->folders, path_or_uri);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
+
+ return folder;
}
static int
@@ -1930,11 +1968,13 @@
g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
folders = g_ptr_array_new ();
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
/* if (account->priv->fresh_folders)
g_hash_table_foreach (account->priv->fresh_folders, add_folder, folders);
else
*/
g_hash_table_foreach (account->priv->folders, add_folder, folders);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
qsort (folders->pdata, folders->len,
sizeof (EFolder *), folder_comparator);
@@ -1975,11 +2015,13 @@
fld_tree->path = path;
fld_tree->folders = folders;
+ g_static_rec_mutex_lock (&account->priv->folders_lock);
/* if (account->priv->fresh_folders)
g_hash_table_foreach (account->priv->fresh_folders, add_folder, folders);
else
*/
g_hash_table_foreach (account->priv->folders, add_folder_tree, fld_tree);
+ g_static_rec_mutex_unlock (&account->priv->folders_lock);
qsort (folders->pdata, folders->len,
sizeof (EFolder *), folder_comparator);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]