[evolution-data-server] CamelIMAPXConnManager: Give ConnectionInfo its own mutex.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelIMAPXConnManager: Give ConnectionInfo its own mutex.
- Date: Mon, 23 Jan 2012 22:12:16 +0000 (UTC)
commit 2651fa606076c59c5384835ce452e1cc56ed5745
Author: Matthew Barnes <mbarnes redhat com>
Date: Mon Jan 23 11:31:33 2012 -0500
CamelIMAPXConnManager: Give ConnectionInfo its own mutex.
Define a bunch of simple thread-safe operations for it:
connection_info_is_available
connection_info_has_folder_name
connection_info_insert_folder_name
connection_info_remove_folder_name
connection_info_dup_selected_folder
connection_info_set_selected_folder
camel/providers/imapx/camel-imapx-conn-manager.c | 143 +++++++++++++++++++---
1 files changed, 124 insertions(+), 19 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c b/camel/providers/imapx/camel-imapx-conn-manager.c
index d15e0d8..c80d796 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -43,8 +43,9 @@ struct _CamelIMAPXConnManagerPrivate {
};
struct _ConnectionInfo {
- GHashTable *folders;
+ GMutex *lock;
CamelIMAPXServer *is;
+ GHashTable *folder_names;
gchar *selected_folder;
volatile gint ref_count;
};
@@ -63,17 +64,18 @@ static ConnectionInfo *
connection_info_new (CamelIMAPXServer *is)
{
ConnectionInfo *cinfo;
- GHashTable *folders;
+ GHashTable *folder_names;
- folders = g_hash_table_new_full (
+ folder_names = g_hash_table_new_full (
(GHashFunc) g_str_hash,
(GEqualFunc) g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) NULL);
cinfo = g_slice_new0 (ConnectionInfo);
- cinfo->folders = folders;
+ cinfo->lock = g_mutex_new ();
cinfo->is = g_object_ref (is);
+ cinfo->folder_names = folder_names;
cinfo->ref_count = 1;
return cinfo;
@@ -99,14 +101,113 @@ connection_info_unref (ConnectionInfo *cinfo)
if (g_atomic_int_dec_and_test (&cinfo->ref_count)) {
camel_imapx_server_connect (cinfo->is, NULL, NULL);
+ g_mutex_free (cinfo->lock);
g_object_unref (cinfo->is);
- g_hash_table_destroy (cinfo->folders);
+ g_hash_table_destroy (cinfo->folder_names);
g_free (cinfo->selected_folder);
g_slice_free (ConnectionInfo, cinfo);
}
}
+static gboolean
+connection_info_is_available (ConnectionInfo *cinfo)
+{
+ gboolean available;
+
+ g_return_val_if_fail (cinfo != NULL, FALSE);
+
+ g_mutex_lock (cinfo->lock);
+
+ /* Available means it's not tracking any folder names. */
+ available = (g_hash_table_size (cinfo->folder_names) == 0);
+
+ g_mutex_unlock (cinfo->lock);
+
+ return available;
+}
+
+static gboolean
+connection_info_has_folder_name (ConnectionInfo *cinfo,
+ const gchar *folder_name)
+{
+ gpointer value;
+
+ g_return_val_if_fail (cinfo != NULL, FALSE);
+
+ if (folder_name == NULL)
+ return FALSE;
+
+ g_mutex_lock (cinfo->lock);
+
+ value = g_hash_table_lookup (cinfo->folder_names, folder_name);
+
+ g_mutex_unlock (cinfo->lock);
+
+ return (value != NULL);
+}
+
+static void
+connection_info_insert_folder_name (ConnectionInfo *cinfo,
+ const gchar *folder_name)
+{
+ g_return_if_fail (cinfo != NULL);
+ g_return_if_fail (folder_name != NULL);
+
+ g_mutex_lock (cinfo->lock);
+
+ g_hash_table_insert (
+ cinfo->folder_names,
+ g_strdup (folder_name),
+ GINT_TO_POINTER (1));
+
+ g_mutex_unlock (cinfo->lock);
+}
+
+static void
+connection_info_remove_folder_name (ConnectionInfo *cinfo,
+ const gchar *folder_name)
+{
+ g_return_if_fail (cinfo != NULL);
+ g_return_if_fail (folder_name != NULL);
+
+ g_mutex_lock (cinfo->lock);
+
+ g_hash_table_remove (cinfo->folder_names, folder_name);
+
+ g_mutex_unlock (cinfo->lock);
+}
+
+static gchar *
+connection_info_dup_selected_folder (ConnectionInfo *cinfo)
+{
+ gchar *selected_folder;
+
+ g_return_val_if_fail (cinfo != NULL, NULL);
+
+ g_mutex_lock (cinfo->lock);
+
+ selected_folder = g_strdup (cinfo->selected_folder);
+
+ g_mutex_unlock (cinfo->lock);
+
+ return selected_folder;
+}
+
+static void
+connection_info_set_selected_folder (ConnectionInfo *cinfo,
+ const gchar *selected_folder)
+{
+ g_return_if_fail (cinfo != NULL);
+
+ g_mutex_lock (cinfo->lock);
+
+ g_free (cinfo->selected_folder);
+ cinfo->selected_folder = g_strdup (selected_folder);
+
+ g_mutex_unlock (cinfo->lock);
+}
+
static void
imapx_prune_connections (CamelIMAPXConnManager *con_man)
{
@@ -296,19 +397,24 @@ imapx_conn_update_select (CamelIMAPXServer *is,
}
if (found) {
- if (cinfo->selected_folder) {
+ gchar *old_selected_folder;
+
+ old_selected_folder =
+ connection_info_dup_selected_folder (cinfo);
+
+ if (old_selected_folder != NULL) {
IMAPXJobQueueInfo *jinfo;
jinfo = camel_imapx_server_get_job_queue_info (cinfo->is);
- if (!g_hash_table_lookup (jinfo->folders, cinfo->selected_folder)) {
- g_hash_table_remove (cinfo->folders, cinfo->selected_folder);
- c(is->tagprefix, "Removed folder %s from connection folder list - select changed \n", cinfo->selected_folder);
+ if (!g_hash_table_lookup (jinfo->folders, old_selected_folder)) {
+ connection_info_remove_folder_name (cinfo, old_selected_folder);
+ c(is->tagprefix, "Removed folder %s from connection folder list - select changed \n", old_selected_folder);
}
camel_imapx_destroy_job_queue_info (jinfo);
- g_free (cinfo->selected_folder);
+ g_free (old_selected_folder);
}
- cinfo->selected_folder = g_strdup (selected_folder);
+ connection_info_set_selected_folder (cinfo, selected_folder);
}
CON_UNLOCK (con_man);
@@ -353,11 +459,10 @@ imapx_find_connection (CamelIMAPXConnManager *con_man,
camel_imapx_destroy_job_queue_info (jinfo);
- if (folder_name && (g_hash_table_lookup (cinfo->folders, folder_name) || g_hash_table_size (cinfo->folders) == 0)) {
+ if (folder_name != NULL && (connection_info_has_folder_name (cinfo, folder_name) || connection_info_is_available (cinfo))) {
is = g_object_ref (cinfo->is);
- if (folder_name)
- g_hash_table_insert (cinfo->folders, g_strdup (folder_name), GINT_TO_POINTER (1));
+ connection_info_insert_folder_name (cinfo, folder_name);
c(is->tagprefix, "Found connection for %s and connection number %d \n", folder_name, i+1);
break;
}
@@ -367,8 +472,8 @@ imapx_find_connection (CamelIMAPXConnManager *con_man,
cinfo = g_list_nth_data (con_man->priv->connections, n);
is = g_object_ref (cinfo->is);
- if (folder_name) {
- g_hash_table_insert (cinfo->folders, g_strdup (folder_name), GINT_TO_POINTER (1));
+ if (folder_name != NULL) {
+ connection_info_insert_folder_name (cinfo, folder_name);
c(is->tagprefix, "Adding folder %s to connection number %d \n", folder_name, n+1);
}
}
@@ -445,8 +550,8 @@ imapx_create_new_connection (CamelIMAPXConnManager *con_man,
g_object_unref (is);
- if (folder_name)
- g_hash_table_insert (cinfo->folders, g_strdup (folder_name), GINT_TO_POINTER (1));
+ if (folder_name != NULL)
+ connection_info_insert_folder_name (cinfo, folder_name);
con_man->priv->connections = g_list_prepend (con_man->priv->connections, cinfo);
@@ -542,7 +647,7 @@ camel_imapx_conn_manager_update_con_info (CamelIMAPXConnManager *con_man,
jinfo = camel_imapx_server_get_job_queue_info (cinfo->is);
if (!g_hash_table_lookup (jinfo->folders, folder_name)) {
- g_hash_table_remove (cinfo->folders, folder_name);
+ connection_info_remove_folder_name (cinfo, folder_name);
c(is->tagprefix, "Removed folder %s from connection folder list - op done \n", folder_name);
}
camel_imapx_destroy_job_queue_info (jinfo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]