[evolution-data-server] Have camel_session_list_services() return new references.



commit f5ae84279d39752897df0f3213e34165d50e582d
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun Aug 12 09:11:08 2012 -0400

    Have camel_session_list_services() return new references.
    
    Applying lessons learned from ESourceRegistry.
    
    When returning a pointer to a reference-counted object in a multi-
    threaded environment, always increase the object's reference count
    before returning so as to transfer a new reference to the caller.
    
    Otherwise it introduces a potential race where the reference-counted
    object may lose its last reference and be freed while the caller is
    still using the object.  Even if the caller immediately increments
    the object's reference count, it's still a potential race.
    
    Transferring a new reference to the caller means the caller must
    unreference the object when finished with it so the object will be
    properly freed when it's no longer needed.
    
    Making subtle behavioral changes like this without renaming the API
    is usually considered bad, but since Evolution is the only consumer
    we can easily keep the side-effects under control.

 camel/camel-session.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 9a75b1d..ee6f9af 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -1098,7 +1098,7 @@ camel_session_get_service_by_url (CamelSession *session,
 			break;
 	}
 
-	g_list_free (list);
+	g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
 	return match;
 }
@@ -1108,7 +1108,17 @@ camel_session_get_service_by_url (CamelSession *session,
  * @session: a #CamelSession
  *
  * Returns a list of all #CamelService objects previously added using
- * camel_session_add_service().  Free the returned list using g_list_free().
+ * camel_session_add_service().
+ *
+ * The services returned in the list are referenced for thread-safety.
+ * They must each be unreferenced with g_object_unref() when finished
+ * with them.  Free the returned list itself with g_list_free().
+ *
+ * An easy way to free the list property in one step is as follows:
+ *
+ * |[
+ *   g_list_free_full (list, g_object_unref);
+ * ]|
  *
  * Returns: an unsorted list of #CamelService objects
  *
@@ -1125,6 +1135,8 @@ camel_session_list_services (CamelSession *session)
 
 	list = g_hash_table_get_values (session->priv->services);
 
+	g_list_foreach (list, (GFunc) g_object_ref, NULL);
+
 	g_mutex_unlock (session->priv->services_lock);
 
 	return list;



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