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.
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));