[evolution-data-server] I#24 - The 'contacts' calendar backend leaks BookRecord
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#24 - The 'contacts' calendar backend leaks BookRecord
- Date: Wed, 12 Sep 2018 11:55:29 +0000 (UTC)
commit a93d40246c9a4f3a18a8af52a15fe92c2b638063
Author: Milan Crha <mcrha redhat com>
Date: Fri Sep 7 11:55:05 2018 +0200
I#24 - The 'contacts' calendar backend leaks BookRecord
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/24
.../backends/contacts/e-cal-backend-contacts.c | 54 ++++++++++++++--------
1 file changed, 36 insertions(+), 18 deletions(-)
---
diff --git a/src/calendar/backends/contacts/e-cal-backend-contacts.c
b/src/calendar/backends/contacts/e-cal-backend-contacts.c
index ef6054fac..c91079fba 100644
--- a/src/calendar/backends/contacts/e-cal-backend-contacts.c
+++ b/src/calendar/backends/contacts/e-cal-backend-contacts.c
@@ -79,6 +79,7 @@ typedef struct _BookRecord {
ECalBackendContacts *cbc;
EBookClient *book_client;
EBookClientView *book_view;
+ GCancellable *cancellable;
gboolean online;
gulong notify_online_id;
} BookRecord;
@@ -143,9 +144,9 @@ create_book_record (ECalBackendContacts *cbc,
br->ref_count = 1;
g_mutex_init (&br->lock);
br->cbc = g_object_ref (cbc);
+ br->cancellable = g_cancellable_new ();
- e_book_client_connect (
- source, 30, NULL, book_client_connected_cb, br);
+ e_book_client_connect (source, 30, br->cancellable, book_client_connected_cb, br);
}
static BookRecord *
@@ -166,26 +167,43 @@ book_record_unref (BookRecord *br)
g_return_if_fail (br->ref_count > 0);
if (g_atomic_int_dec_and_test (&br->ref_count)) {
- g_rec_mutex_lock (&br->cbc->priv->tracked_contacts_lock);
- g_hash_table_foreach_remove (
- br->cbc->priv->tracked_contacts,
- remove_by_book, br->book_client);
- g_rec_mutex_unlock (&br->cbc->priv->tracked_contacts_lock);
+ g_cancellable_cancel (br->cancellable);
+
+ if (br->book_client) {
+ g_rec_mutex_lock (&br->cbc->priv->tracked_contacts_lock);
+ g_hash_table_foreach_remove (
+ br->cbc->priv->tracked_contacts,
+ remove_by_book, br->book_client);
+ g_rec_mutex_unlock (&br->cbc->priv->tracked_contacts_lock);
+ }
+
+ g_mutex_lock (&br->lock);
if (br->notify_online_id)
g_signal_handler_disconnect (br->book_client, br->notify_online_id);
- g_mutex_clear (&br->lock);
- g_object_unref (br->cbc);
- g_object_unref (br->book_client);
+ g_clear_object (&br->cbc);
+ g_clear_object (&br->cancellable);
+ g_clear_object (&br->book_client);
+ g_clear_object (&br->book_view);
- if (br->book_view != NULL)
- g_object_unref (br->book_view);
+ g_mutex_unlock (&br->lock);
+ g_mutex_clear (&br->lock);
g_slice_free (BookRecord, br);
}
}
+static void
+cancel_and_unref_book_record (BookRecord *br)
+{
+ g_return_if_fail (br != NULL);
+
+ if (br->cancellable)
+ g_cancellable_cancel (br->cancellable);
+ book_record_unref (br);
+}
+
static void
book_record_set_book_view (BookRecord *br,
EBookClientView *book_view)
@@ -264,8 +282,7 @@ book_record_get_view_thread (gpointer user_data)
query_sexp = e_book_query_to_string (query);
e_book_query_unref (query);
- if (!e_book_client_get_view_sync (
- br->book_client, query_sexp, &book_view, NULL, &error)) {
+ if (!e_book_client_get_view_sync (br->book_client, query_sexp, &book_view, br->cancellable, &error)) {
if (!error)
error = g_error_new_literal (
@@ -390,7 +407,7 @@ book_client_connected_cb (GObject *source_object,
g_warning ("%s: %s", G_STRFUNC, error->message);
g_error_free (error);
- g_slice_free (BookRecord, br);
+ book_record_unref (br);
return;
}
@@ -400,8 +417,8 @@ book_client_connected_cb (GObject *source_object,
br->notify_online_id = g_signal_connect (client, "notify::online", G_CALLBACK
(book_client_notify_online_cb), br);
cal_backend_contacts_insert_book_record (br->cbc, source, br);
- thread = g_thread_new (
- NULL, book_record_get_view_thread, book_record_ref (br));
+ /* Let it consume the 'br' reference */
+ thread = g_thread_new (NULL, book_record_get_view_thread, br);
g_thread_unref (thread);
g_object_unref (client);
@@ -552,6 +569,7 @@ ecb_contacts_watcher_appeared_cb (ESourceRegistryWatcher *watcher,
g_return_if_fail (E_IS_SOURCE (source));
g_return_if_fail (E_IS_CAL_BACKEND_CONTACTS (cbcontacts));
+ cal_backend_contacts_remove_book_record (cbcontacts, source);
create_book_record (cbcontacts, source);
}
@@ -1365,7 +1383,7 @@ e_cal_backend_contacts_init (ECalBackendContacts *cbc)
(GHashFunc) e_source_hash,
(GEqualFunc) e_source_equal,
(GDestroyNotify) g_object_unref,
- (GDestroyNotify) book_record_unref);
+ (GDestroyNotify) cancel_and_unref_book_record);
cbc->priv->tracked_contacts = g_hash_table_new_full (
(GHashFunc) g_str_hash,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]