[evolution-data-server] Camel: Add thread-safe accessors for string settings



commit e1983a7d9608d906db4994a5bddaebf88b49f5df
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Jan 3 00:34:11 2012 -0500

    Camel: Add thread-safe accessors for string settings

 camel/camel-local-settings.c                 |   43 +++++-
 camel/camel-local-settings.h                 |    1 +
 camel/camel-network-settings.c               |  110 +++++++++++++
 camel/camel-network-settings.h               |    6 +
 camel/providers/imap/camel-imap-settings.c   |  226 ++++++++++++++++++++++----
 camel/providers/imap/camel-imap-settings.h   |   10 ++
 camel/providers/imapx/camel-imapx-settings.c |   94 ++++++++++--
 camel/providers/imapx/camel-imapx-settings.h |    4 +
 camel/providers/nntp/camel-nntp-settings.c   |   12 +-
 camel/providers/pop3/camel-pop3-settings.c   |   12 +-
 camel/providers/smtp/camel-smtp-settings.c   |   12 +-
 docs/reference/camel/camel-sections.txt      |    4 +
 12 files changed, 475 insertions(+), 59 deletions(-)
---
diff --git a/camel/camel-local-settings.c b/camel/camel-local-settings.c
index d55e4ac..5201661 100644
--- a/camel/camel-local-settings.c
+++ b/camel/camel-local-settings.c
@@ -25,6 +25,7 @@
 	((obj), CAMEL_TYPE_LOCAL_SETTINGS, CamelLocalSettingsPrivate))
 
 struct _CamelLocalSettingsPrivate {
+	GMutex *property_lock;
 	gchar *path;
 };
 
@@ -63,9 +64,9 @@ local_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_PATH:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_local_settings_get_path (
+				camel_local_settings_dup_path (
 				CAMEL_LOCAL_SETTINGS (object)));
 			return;
 	}
@@ -80,6 +81,8 @@ local_settings_finalize (GObject *object)
 
 	priv = CAMEL_LOCAL_SETTINGS_GET_PRIVATE (object);
 
+	g_mutex_free (priv->property_lock);
+
 	g_free (priv->path);
 
 	/* Chain up to parent's finalize() method. */
@@ -115,6 +118,7 @@ static void
 camel_local_settings_init (CamelLocalSettings *settings)
 {
 	settings->priv = CAMEL_LOCAL_SETTINGS_GET_PRIVATE (settings);
+	settings->priv->property_lock = g_mutex_new ();
 }
 
 /**
@@ -136,6 +140,37 @@ camel_local_settings_get_path (CamelLocalSettings *settings)
 }
 
 /**
+ * camel_local_settings_dup_path:
+ * @settings: a #CamelLocalSettings
+ *
+ * Thread-safe variation of camel_local_settings_get_path().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelLocalSettings:path
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_local_settings_dup_path (CamelLocalSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_LOCAL_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_local_settings_get_path (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_local_settings_set_path:
  * @settings: a #CamelLocalSettings
  * @path: the file path to the local store
@@ -165,9 +200,13 @@ camel_local_settings_set_path (CamelLocalSettings *settings,
 		}
 	}
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->path);
 	settings->priv->path = g_strndup (path, length);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "path");
 }
 
diff --git a/camel/camel-local-settings.h b/camel/camel-local-settings.h
index 31a7eb2..331e3a8 100644
--- a/camel/camel-local-settings.h
+++ b/camel/camel-local-settings.h
@@ -69,6 +69,7 @@ struct _CamelLocalSettingsClass {
 
 GType		camel_local_settings_get_type	(void) G_GNUC_CONST;
 const gchar *	camel_local_settings_get_path	(CamelLocalSettings *settings);
+gchar *		camel_local_settings_dup_path	(CamelLocalSettings *settings);
 void		camel_local_settings_set_path	(CamelLocalSettings *settings,
 						 const gchar *path);
 
diff --git a/camel/camel-network-settings.c b/camel/camel-network-settings.c
index e6ca300..cc107b2 100644
--- a/camel/camel-network-settings.c
+++ b/camel/camel-network-settings.c
@@ -27,6 +27,11 @@
 #define SECURITY_METHOD_KEY "CamelNetworkSettings:security-method"
 #define USER_KEY            "CamelNetworkSettings:user"
 
+/* XXX Because interfaces have no initialization method, we can't
+ *     allocate a per-instance mutex in a thread-safe manner.  So
+ *     we have to use a single static mutex for all instances. */
+G_LOCK_DEFINE_STATIC (property_lock);
+
 G_DEFINE_INTERFACE (
 	CamelNetworkSettings,
 	camel_network_settings,
@@ -112,6 +117,37 @@ camel_network_settings_get_auth_mechanism (CamelNetworkSettings *settings)
 }
 
 /**
+ * camel_network_settings_dup_auth_mechanism:
+ * @settings: a #CamelNetworkSettings
+ *
+ * Thread-safe variation of camel_network_settings_get_auth_mechanism().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelNetworkSettings:auth-mechanism
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_network_settings_dup_auth_mechanism (CamelNetworkSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
+
+	G_LOCK (property_lock);
+
+	protected = camel_network_settings_get_auth_mechanism (settings);
+	duplicate = g_strdup (protected);
+
+	G_UNLOCK (property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_network_settings_set_auth_mechanism:
  * @settings: a #CamelNetworkSettings
  * @auth_mechanism: an authentication mechanism name, or %NULL
@@ -136,12 +172,16 @@ camel_network_settings_set_auth_mechanism (CamelNetworkSettings *settings,
 		stripped_auth_mechanism =
 			g_strstrip (g_strdup (auth_mechanism));
 
+	G_LOCK (property_lock);
+
 	g_object_set_data_full (
 		G_OBJECT (settings),
 		AUTH_MECHANISM_KEY,
 		stripped_auth_mechanism,
 		(GDestroyNotify) g_free);
 
+	G_UNLOCK (property_lock);
+
 	g_object_notify (G_OBJECT (settings), "auth-mechanism");
 }
 
@@ -164,6 +204,37 @@ camel_network_settings_get_host (CamelNetworkSettings *settings)
 }
 
 /**
+ * camel_network_settings_dup_host:
+ * @settings: a #CamelNetworkSettings
+ *
+ * Thread-safe variation of camel_network_settings_get_host().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelNetworkSettings:host
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_network_settings_dup_host (CamelNetworkSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
+
+	G_LOCK (property_lock);
+
+	protected = camel_network_settings_get_host (settings);
+	duplicate = g_strdup (protected);
+
+	G_UNLOCK (property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_network_settings_set_host:
  * @settings: a #CamelNetworkSettings
  * @host: a host name, or %NULL
@@ -189,11 +260,15 @@ camel_network_settings_set_host (CamelNetworkSettings *settings,
 	/* Strip leading and trailing whitespace. */
 	stripped_host = g_strstrip (g_strdup (host));
 
+	G_LOCK (property_lock);
+
 	g_object_set_data_full (
 		G_OBJECT (settings),
 		HOST_KEY, stripped_host,
 		(GDestroyNotify) g_free);
 
+	G_UNLOCK (property_lock);
+
 	g_object_notify (G_OBJECT (settings), "host");
 }
 
@@ -310,6 +385,37 @@ camel_network_settings_get_user (CamelNetworkSettings *settings)
 }
 
 /**
+ * camel_network_settings_dup_user:
+ * @settings: a #CamelNetworkSettings
+ *
+ * Thread-safe variation of camel_network_settings_get_user().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelNetworkSettings:user
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_network_settings_dup_user (CamelNetworkSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
+
+	G_LOCK (property_lock);
+
+	protected = camel_network_settings_get_user (settings);
+	duplicate = g_strdup (protected);
+
+	G_UNLOCK (property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_network_settings_set_user:
  * @settings: a #CamelNetworkSettings
  * @user: a user name, or %NULL
@@ -335,11 +441,15 @@ camel_network_settings_set_user (CamelNetworkSettings *settings,
 	/* Strip leading and trailing whitespace. */
 	stripped_user = g_strstrip (g_strdup (user));
 
+	G_LOCK (property_lock);
+
 	g_object_set_data_full (
 		G_OBJECT (settings),
 		USER_KEY, stripped_user,
 		(GDestroyNotify) g_free);
 
+	G_UNLOCK (property_lock);
+
 	g_object_notify (G_OBJECT (settings), "user");
 }
 
diff --git a/camel/camel-network-settings.h b/camel/camel-network-settings.h
index 1049e79..f057305 100644
--- a/camel/camel-network-settings.h
+++ b/camel/camel-network-settings.h
@@ -63,11 +63,15 @@ GType		camel_network_settings_get_type
 					(void) G_GNUC_CONST;
 const gchar *	camel_network_settings_get_auth_mechanism
 					(CamelNetworkSettings *settings);
+gchar *		camel_network_settings_dup_auth_mechanism
+					(CamelNetworkSettings *settings);
 void		camel_network_settings_set_auth_mechanism
 					(CamelNetworkSettings *settings,
 					 const gchar *auth_mechanism);
 const gchar *	camel_network_settings_get_host
 					(CamelNetworkSettings *settings);
+gchar *		camel_network_settings_dup_host
+					(CamelNetworkSettings *settings);
 void		camel_network_settings_set_host
 					(CamelNetworkSettings *settings,
 					 const gchar *host);
@@ -84,6 +88,8 @@ void		camel_network_settings_set_security_method
 					 CamelNetworkSecurityMethod method);
 const gchar *	camel_network_settings_get_user
 					(CamelNetworkSettings *settings);
+gchar *		camel_network_settings_dup_user
+					(CamelNetworkSettings *settings);
 void		camel_network_settings_set_user
 					(CamelNetworkSettings *settings,
 					 const gchar *user);
diff --git a/camel/providers/imap/camel-imap-settings.c b/camel/providers/imap/camel-imap-settings.c
index 4cfcc59..3b6a3fe 100644
--- a/camel/providers/imap/camel-imap-settings.c
+++ b/camel/providers/imap/camel-imap-settings.c
@@ -23,6 +23,7 @@
 	((obj), CAMEL_TYPE_IMAP_SETTINGS, CamelImapSettingsPrivate))
 
 struct _CamelImapSettingsPrivate {
+	GMutex *property_lock;
 	gchar *namespace;
 	gchar *shell_command;
 	gchar *real_junk_path;
@@ -212,9 +213,9 @@ imap_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_AUTH_MECHANISM:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_auth_mechanism (
+				camel_network_settings_dup_auth_mechanism (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -240,9 +241,9 @@ imap_settings_get_property (GObject *object,
 			return;
 
 		case PROP_FETCH_HEADERS_EXTRA:
-			g_value_set_boxed (
+			g_value_take_boxed (
 				value,
-				camel_imap_settings_get_fetch_headers_extra (
+				camel_imap_settings_dup_fetch_headers_extra (
 				CAMEL_IMAP_SETTINGS (object)));
 			return;
 
@@ -261,16 +262,16 @@ imap_settings_get_property (GObject *object,
 			return;
 
 		case PROP_HOST:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_host (
+				camel_network_settings_dup_host (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
 		case PROP_NAMESPACE:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imap_settings_get_namespace (
+				camel_imap_settings_dup_namespace (
 				CAMEL_IMAP_SETTINGS (object)));
 			return;
 
@@ -282,16 +283,16 @@ imap_settings_get_property (GObject *object,
 			return;
 
 		case PROP_REAL_JUNK_PATH:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imap_settings_get_real_junk_path (
+				camel_imap_settings_dup_real_junk_path (
 				CAMEL_IMAP_SETTINGS (object)));
 			return;
 
 		case PROP_REAL_TRASH_PATH:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imap_settings_get_real_trash_path (
+				camel_imap_settings_dup_real_trash_path (
 				CAMEL_IMAP_SETTINGS (object)));
 			return;
 
@@ -303,16 +304,16 @@ imap_settings_get_property (GObject *object,
 			return;
 
 		case PROP_SHELL_COMMAND:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imap_settings_get_shell_command (
+				camel_imap_settings_dup_shell_command (
 				CAMEL_IMAP_SETTINGS (object)));
 			return;
 
 		case PROP_USER:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_user (
+				camel_network_settings_dup_user (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -362,6 +363,8 @@ imap_settings_finalize (GObject *object)
 
 	priv = CAMEL_IMAP_SETTINGS_GET_PRIVATE (object);
 
+	g_mutex_free (priv->property_lock);
+
 	g_free (priv->namespace);
 	g_free (priv->shell_command);
 	g_free (priv->real_junk_path);
@@ -601,6 +604,7 @@ static void
 camel_imap_settings_init (CamelImapSettings *settings)
 {
 	settings->priv = CAMEL_IMAP_SETTINGS_GET_PRIVATE (settings);
+	settings->priv->property_lock = g_mutex_new ();
 }
 
 /**
@@ -747,6 +751,38 @@ camel_imap_settings_get_fetch_headers_extra (CamelImapSettings *settings)
 }
 
 /**
+ * camel_imap_settings_dup_fetch_headers_extra:
+ * @settings: a #CamelImapSettings
+ *
+ * Thread-safe variation of camel_imap_settings_get_fetch_headers_extra().
+ * Use this function when accessing @extension from a worker thread.
+ *
+ * The returned string array should be freed with g_strfreev() when no
+ * longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelImapSettings:fetch-headers-extra
+ *
+ * Since: 3.4
+ **/
+gchar **
+camel_imap_settings_dup_fetch_headers_extra (CamelImapSettings *settings)
+{
+	const gchar * const *protected;
+	gchar **duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAP_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imap_settings_get_fetch_headers_extra (settings);
+	duplicate = g_strdupv ((gchar **) protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imap_settings_set_fetch_headers_extra:
  * @settings: a #CamelImapSettings
  * @fetch_headers_extra: a %NULL-terminated list of extra headers to fetch,
@@ -763,23 +799,15 @@ void
 camel_imap_settings_set_fetch_headers_extra (CamelImapSettings *settings,
                                              const gchar * const *fetch_headers_extra)
 {
-	gchar **strv = NULL;
-
 	g_return_if_fail (CAMEL_IS_IMAP_SETTINGS (settings));
 
-	g_strfreev (settings->priv->fetch_headers_extra);
-
-	if (fetch_headers_extra != NULL) {
-		guint ii, length;
-
-		length = g_strv_length ((gchar **) fetch_headers_extra);
-		strv = g_new0 (gchar *, length + 1);
+	g_mutex_lock (settings->priv->property_lock);
 
-		for (ii = 0; ii < length; ii++)
-			strv[ii] = g_strdup (fetch_headers_extra[ii]);
-	}
+	g_strfreev (settings->priv->fetch_headers_extra);
+	settings->priv->fetch_headers_extra =
+		g_strdupv ((gchar **) fetch_headers_extra);
 
-	settings->priv->fetch_headers_extra = strv;
+	g_mutex_unlock (settings->priv->property_lock);
 
 	g_object_notify (G_OBJECT (settings), "fetch-headers-extra");
 }
@@ -883,6 +911,37 @@ camel_imap_settings_get_namespace (CamelImapSettings *settings)
 }
 
 /**
+ * camel_imap_settings_dup_namespace:
+ * @settings: a #CamelImapSettings
+ *
+ * Thread-safe variation of camel_imap_settings_get_namespace().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelImapSettings:namespace
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imap_settings_dup_namespace (CamelImapSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAP_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imap_settings_get_namespace (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imap_settings_set_namespace:
  * @settings: a #CamelImapSettings
  * @namespace: an IMAP namespace, or %NULL
@@ -902,9 +961,13 @@ camel_imap_settings_set_namespace (CamelImapSettings *settings,
 	if (namespace == NULL)
 		namespace = "";
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->namespace);
 	settings->priv->namespace = g_strdup (namespace);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "namespace");
 }
 
@@ -928,6 +991,37 @@ camel_imap_settings_get_real_junk_path (CamelImapSettings *settings)
 }
 
 /**
+ * camel_imap_settings_dup_real_junk_path:
+ * @settings: a #CamelImapSettings
+ *
+ * Thread-safe variation of camel_imap_settings_get_real_junk_path().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelImapSettings:real-junk-path
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imap_settings_dup_real_junk_path (CamelImapSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAP_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imap_settings_get_real_junk_path (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imap_settings_set_real_junk_path:
  * @settings: a #CamelImapSettings
  * @real_junk_path: path to a real Junk folder, or %NULL
@@ -947,9 +1041,13 @@ camel_imap_settings_set_real_junk_path (CamelImapSettings *settings,
 	if (real_junk_path != NULL && *real_junk_path == '\0')
 		real_junk_path = NULL;
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->real_junk_path);
 	settings->priv->real_junk_path = g_strdup (real_junk_path);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "real-junk-path");
 }
 
@@ -973,6 +1071,37 @@ camel_imap_settings_get_real_trash_path (CamelImapSettings *settings)
 }
 
 /**
+ * camel_imap_settings_dup_real_trash_path:
+ * @settings: a #CamelImapSettings
+ *
+ * Thread-safe variation of camel_imap_settings_get_real_trash_path().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelImapSettings:real-trash-path
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imap_settings_dup_real_trash_path (CamelImapSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAP_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imap_settings_get_real_trash_path (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imap_settings_set_real_trash_path:
  * @settings: a #CamelImapSettings
  * @real_trash_path: path to a real Trash folder, or %NULL
@@ -992,9 +1121,13 @@ camel_imap_settings_set_real_trash_path (CamelImapSettings *settings,
 	if (real_trash_path != NULL && *real_trash_path == '\0')
 		real_trash_path = NULL;
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->real_trash_path);
 	settings->priv->real_trash_path = g_strdup (real_trash_path);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "real-trash-path");
 }
 
@@ -1024,6 +1157,37 @@ camel_imap_settings_get_shell_command (CamelImapSettings *settings)
 }
 
 /**
+ * camel_imap_settings_dup_shell_command:
+ * @settings: a #CamelImapSettings
+ *
+ * Thread-safe variation of camel_imap_settings_get_shell_command().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelImapSettings:shell-command
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imap_settings_dup_shell_command (CamelImapSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAP_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imap_settings_get_shell_command (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imap_settings_set_shell_command:
  * @settings: a #CamelImapSettings
  * @shell_command: shell command for connecting to the server, or %NULL
@@ -1049,9 +1213,13 @@ camel_imap_settings_set_shell_command (CamelImapSettings *settings,
 	if (shell_command != NULL && *shell_command == '\0')
 		shell_command = NULL;
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->shell_command);
 	settings->priv->shell_command = g_strdup (shell_command);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "shell-command");
 }
 
diff --git a/camel/providers/imap/camel-imap-settings.h b/camel/providers/imap/camel-imap-settings.h
index b02d563..2d1aa7a 100644
--- a/camel/providers/imap/camel-imap-settings.h
+++ b/camel/providers/imap/camel-imap-settings.h
@@ -76,6 +76,8 @@ void		camel_imap_settings_set_fetch_headers
 const gchar * const *
 		camel_imap_settings_get_fetch_headers_extra
 					(CamelImapSettings *settings);
+gchar **	camel_imap_settings_dup_fetch_headers_extra
+					(CamelImapSettings *settings);
 void		camel_imap_settings_set_fetch_headers_extra
 					(CamelImapSettings *settings,
 					 const gchar * const *fetch_headers_extra);
@@ -91,21 +93,29 @@ void		camel_imap_settings_set_filter_junk_inbox
 					 gboolean filter_junk_inbox);
 const gchar *	camel_imap_settings_get_namespace
 					(CamelImapSettings *settings);
+gchar *		camel_imap_settings_dup_namespace
+					(CamelImapSettings *settings);
 void		camel_imap_settings_set_namespace
 					(CamelImapSettings *settings,
 					 const gchar *namespace_);
 const gchar *	camel_imap_settings_get_real_junk_path
 					(CamelImapSettings *settings);
+gchar *		camel_imap_settings_dup_real_junk_path
+					(CamelImapSettings *settings);
 void		camel_imap_settings_set_real_junk_path
 					(CamelImapSettings *settings,
 					 const gchar *real_junk_path);
 const gchar *	camel_imap_settings_get_real_trash_path
 					(CamelImapSettings *settings);
+gchar *		camel_imap_settings_dup_real_trash_path
+					(CamelImapSettings *settings);
 void		camel_imap_settings_set_real_trash_path
 					(CamelImapSettings *settings,
 					 const gchar *real_trash_path);
 const gchar *	camel_imap_settings_get_shell_command
 					(CamelImapSettings *settings);
+gchar *		camel_imap_settings_dup_shell_command
+					(CamelImapSettings *settings);
 void		camel_imap_settings_set_shell_command
 					(CamelImapSettings *settings,
 					 const gchar *shell_command);
diff --git a/camel/providers/imapx/camel-imapx-settings.c b/camel/providers/imapx/camel-imapx-settings.c
index d880a0e..0ffdc46 100644
--- a/camel/providers/imapx/camel-imapx-settings.c
+++ b/camel/providers/imapx/camel-imapx-settings.c
@@ -26,6 +26,7 @@
 	((obj), CAMEL_TYPE_IMAPX_SETTINGS, CamelIMAPXSettingsPrivate))
 
 struct _CamelIMAPXSettingsPrivate {
+	GMutex *property_lock;
 	gchar *namespace;
 	gchar *shell_command;
 
@@ -208,9 +209,9 @@ imapx_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_AUTH_MECHANISM:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_auth_mechanism (
+				camel_network_settings_dup_auth_mechanism (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -264,16 +265,16 @@ imapx_settings_get_property (GObject *object,
 			return;
 
 		case PROP_HOST:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_host (
+				camel_network_settings_dup_host (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
 		case PROP_NAMESPACE:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imapx_settings_get_namespace (
+				camel_imapx_settings_dup_namespace (
 				CAMEL_IMAPX_SETTINGS (object)));
 			return;
 
@@ -292,16 +293,16 @@ imapx_settings_get_property (GObject *object,
 			return;
 
 		case PROP_SHELL_COMMAND:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_imapx_settings_get_shell_command (
+				camel_imapx_settings_dup_shell_command (
 				CAMEL_IMAPX_SETTINGS (object)));
 			return;
 
 		case PROP_USER:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_user (
+				camel_network_settings_dup_user (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -351,6 +352,8 @@ imapx_settings_finalize (GObject *object)
 
 	priv = CAMEL_IMAPX_SETTINGS_GET_PRIVATE (object);
 
+	g_mutex_free (priv->property_lock);
+
 	g_free (priv->namespace);
 	g_free (priv->shell_command);
 
@@ -579,6 +582,7 @@ static void
 camel_imapx_settings_init (CamelIMAPXSettings *settings)
 {
 	settings->priv = CAMEL_IMAPX_SETTINGS_GET_PRIVATE (settings);
+	settings->priv->property_lock = g_mutex_new ();
 }
 
 /**
@@ -891,6 +895,37 @@ camel_imapx_settings_get_namespace (CamelIMAPXSettings *settings)
 }
 
 /**
+ * camel_imapx_settings_dup_namespace:
+ * @settings: a #CamelIMAPXSettings
+ *
+ * Thread-safe variation of camel_imapx_settings_get_namespace().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelIMAPXSettings:namespace
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imapx_settings_dup_namespace (CamelIMAPXSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAPX_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imapx_settings_get_namespace (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imapx_settings_set_namespace:
  * @settings: a #CamelIMAPXSettings
  * @namespace: an IMAP namespace, or %NULL
@@ -910,9 +945,13 @@ camel_imapx_settings_set_namespace (CamelIMAPXSettings *settings,
 	if (namespace == NULL)
 		namespace = "";
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->namespace);
 	settings->priv->namespace = g_strdup (namespace);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "namespace");
 }
 
@@ -942,6 +981,37 @@ camel_imapx_settings_get_shell_command (CamelIMAPXSettings *settings)
 }
 
 /**
+ * camel_imapx_settings_dup_shell_command:
+ * @settings: a #CamelIMAPXSettings
+ *
+ * Thread-safe variation of camel_imapx_settings_get_shell_command().
+ * Use this function when accessing @settings from a worker thread.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelIMAPXSettings:shell-command
+ *
+ * Since: 3.4
+ **/
+gchar *
+camel_imapx_settings_dup_shell_command (CamelIMAPXSettings *settings)
+{
+	const gchar *protected;
+	gchar *duplicate;
+
+	g_return_val_if_fail (CAMEL_IS_IMAPX_SETTINGS (settings), NULL);
+
+	g_mutex_lock (settings->priv->property_lock);
+
+	protected = camel_imapx_settings_get_shell_command (settings);
+	duplicate = g_strdup (protected);
+
+	g_mutex_unlock (settings->priv->property_lock);
+
+	return duplicate;
+}
+
+/**
  * camel_imapx_settings_set_shell_command:
  * @settings: a #CamelIMAPXSettings
  * @shell_command: shell command for connecting to the server, or %NULL
@@ -967,9 +1037,13 @@ camel_imapx_settings_set_shell_command (CamelIMAPXSettings *settings,
 	if (shell_command != NULL && *shell_command == '\0')
 		shell_command = NULL;
 
+	g_mutex_lock (settings->priv->property_lock);
+
 	g_free (settings->priv->shell_command);
 	settings->priv->shell_command = g_strdup (shell_command);
 
+	g_mutex_unlock (settings->priv->property_lock);
+
 	g_object_notify (G_OBJECT (settings), "shell-command");
 }
 
diff --git a/camel/providers/imapx/camel-imapx-settings.h b/camel/providers/imapx/camel-imapx-settings.h
index e63a01a..54f810c 100644
--- a/camel/providers/imapx/camel-imapx-settings.h
+++ b/camel/providers/imapx/camel-imapx-settings.h
@@ -93,11 +93,15 @@ void		camel_imapx_settings_set_filter_junk_inbox
 						 gboolean filter_junk_inbox);
 const gchar *	camel_imapx_settings_get_namespace
 						(CamelIMAPXSettings *settings);
+gchar *		camel_imapx_settings_dup_namespace
+						(CamelIMAPXSettings *settings);
 void		camel_imapx_settings_set_namespace
 						(CamelIMAPXSettings *settings,
 						 const gchar *namespace_);
 const gchar *	camel_imapx_settings_get_shell_command
 						(CamelIMAPXSettings *settings);
+gchar *		camel_imapx_settings_dup_shell_command
+						(CamelIMAPXSettings *settings);
 void		camel_imapx_settings_set_shell_command
 						(CamelIMAPXSettings *settings,
 						 const gchar *shell_command);
diff --git a/camel/providers/nntp/camel-nntp-settings.c b/camel/providers/nntp/camel-nntp-settings.c
index 1cade9b..7990655 100644
--- a/camel/providers/nntp/camel-nntp-settings.c
+++ b/camel/providers/nntp/camel-nntp-settings.c
@@ -106,9 +106,9 @@ nntp_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_AUTH_MECHANISM:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_auth_mechanism (
+				camel_network_settings_dup_auth_mechanism (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -120,9 +120,9 @@ nntp_settings_get_property (GObject *object,
 			return;
 
 		case PROP_HOST:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_host (
+				camel_network_settings_dup_host (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -148,9 +148,9 @@ nntp_settings_get_property (GObject *object,
 			return;
 
 		case PROP_USER:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_user (
+				camel_network_settings_dup_user (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 	}
diff --git a/camel/providers/pop3/camel-pop3-settings.c b/camel/providers/pop3/camel-pop3-settings.c
index 070e421..aba2d05 100644
--- a/camel/providers/pop3/camel-pop3-settings.c
+++ b/camel/providers/pop3/camel-pop3-settings.c
@@ -122,9 +122,9 @@ pop3_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_AUTH_MECHANISM:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_auth_mechanism (
+				camel_network_settings_dup_auth_mechanism (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -150,9 +150,9 @@ pop3_settings_get_property (GObject *object,
 			return;
 
 		case PROP_HOST:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_host (
+				camel_network_settings_dup_host (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -178,9 +178,9 @@ pop3_settings_get_property (GObject *object,
 			return;
 
 		case PROP_USER:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_user (
+				camel_network_settings_dup_user (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 	}
diff --git a/camel/providers/smtp/camel-smtp-settings.c b/camel/providers/smtp/camel-smtp-settings.c
index f1ba57f..2764fa7 100644
--- a/camel/providers/smtp/camel-smtp-settings.c
+++ b/camel/providers/smtp/camel-smtp-settings.c
@@ -87,16 +87,16 @@ smtp_settings_get_property (GObject *object,
 {
 	switch (property_id) {
 		case PROP_AUTH_MECHANISM:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_auth_mechanism (
+				camel_network_settings_dup_auth_mechanism (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
 		case PROP_HOST:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_host (
+				camel_network_settings_dup_host (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 
@@ -115,9 +115,9 @@ smtp_settings_get_property (GObject *object,
 			return;
 
 		case PROP_USER:
-			g_value_set_string (
+			g_value_take_string (
 				value,
-				camel_network_settings_get_user (
+				camel_network_settings_dup_user (
 				CAMEL_NETWORK_SETTINGS (object)));
 			return;
 	}
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index cbb0248..45cdefa 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -864,6 +864,7 @@ camel_junk_filter_get_type
 <TITLE>CamelLocalSettings</TITLE>
 CamelLocalSettings
 camel_local_settings_get_path
+camel_local_settings_dup_path
 camel_local_settings_set_path
 <SUBSECTION Standard>
 CAMEL_LOCAL_SETTINGS
@@ -1514,8 +1515,10 @@ camel_network_service_get_type
 <TITLE>CamelNetworkSettings</TITLE>
 CamelNetworkSettings
 camel_network_settings_get_auth_mechanism
+camel_network_settings_dup_auth_mechanism
 camel_network_settings_set_auth_mechanism
 camel_network_settings_get_host
+camel_network_settings_dup_host
 camel_network_settings_set_host
 camel_network_settings_get_port
 camel_network_settings_set_port
@@ -1523,6 +1526,7 @@ CamelNetworkSecurityMethod
 camel_network_settings_get_security_method
 camel_network_settings_set_security_method
 camel_network_settings_get_user
+camel_network_settings_dup_user
 camel_network_settings_set_user
 <SUBSECTION Standard>
 CAMEL_NETWORK_SETTINGS



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]