ebook: avoid repeatedly creating GSettings in e_book_client_is_self
authorPatrick Ohly <patrick.ohly@intel.com>
Thu, 14 Feb 2013 15:04:14 +0000 (16:04 +0100)
committerPatrick Ohly <patrick.ohly@intel.com>
Fri, 15 Feb 2013 09:56:05 +0000 (10:56 +0100)
When receiving the complete address book, a client has to use
e_book_client_is_self() on every EContact to find the one which is the
"self" contact. Calling e_book_client_get_self() instead does not
work, because that would create the self contact if none exists (not
desired for an app which just reads!).

The problem with e_book_client_is_self() is that it creates and
destroys a GSettings instance for the self UID each time the method is
called. In addition to reading the value over and over again, this
also triggers two D-Bus messages (AddMatch and RemoveMatch) - clearly
bad for performance.

To solve this problem, this patch caches the GSettings instance in a
static variable. It is protected by a mutex, to keep the function
thread-safe. The downside is that the instance is never going to be
freed.

It would be better to attach the GSettings instance to the EBookClient
instance, but because e_book_client_is_self() doesn't get a pointer to
that, this is not possible without an API change.

addressbook/libebook/e-book-client.c

index 4841447..0244841 100644 (file)
@@ -1564,15 +1564,23 @@ e_book_client_set_self (EBookClient *client,
 gboolean
 e_book_client_is_self (EContact *contact)
 {
-       GSettings *settings;
+       static GSettings *settings;
+       static GMutex mutex;
        gchar *uid;
        gboolean is_self;
 
        g_return_val_if_fail (contact && E_IS_CONTACT (contact), FALSE);
 
-       settings = g_settings_new (SELF_UID_PATH_ID);
+       /*
+        * It would be nice to attach this instance to the EBookClient
+        * instance so that it can be free again later, but
+        * unfortunately the API doesn't allow that.
+        */
+       g_mutex_lock (&mutex);
+       if (!settings)
+               settings = g_settings_new (SELF_UID_PATH_ID);
        uid = g_settings_get_string (settings, SELF_UID_KEY);
-       g_object_unref (settings);
+       g_mutex_unlock (&mutex);
 
        is_self = uid && !g_strcmp0 (uid, e_contact_get_const (contact, E_CONTACT_UID));