diff options
author | Milan Crha <mcrha@redhat.com> | 2013-01-22 20:44:41 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2013-01-22 20:44:41 +0100 |
commit | a84d0269dcd3978232cf5dce77ae4a6d7f6107fd (patch) | |
tree | 78022ef57938dcb7ea8da7554bf59b242e4d3c53 | |
parent | bbbeb5e67f98e2f7153685158ccd1bc4668b5185 (diff) | |
download | evolution-data-server-a84d0269dcd3978232cf5dce77ae4a6d7f6107fd.tar.gz |
Bug #692278 - LDAP backend mutex deadlock on finalize
-rw-r--r-- | addressbook/backends/ldap/e-book-backend-ldap.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c index 0de07f26d..1f346ac3e 100644 --- a/addressbook/backends/ldap/e-book-backend-ldap.c +++ b/addressbook/backends/ldap/e-book-backend-ldap.c @@ -214,7 +214,7 @@ struct _EBookBackendLDAPPrivate { gboolean marked_for_offline; /* our operations */ - GStaticRecMutex op_hash_mutex; + GStaticRecMutex op_hash_mutex; /* lock also eds_ldap_handler_lock before this lock */ GHashTable *id_to_op; gint active_ops; guint poll_timeout; @@ -1147,6 +1147,7 @@ ldap_op_add (LDAPOp *op, op->handler = handler; op->dtor = dtor; + g_static_rec_mutex_lock (&eds_ldap_handler_lock); g_static_rec_mutex_lock (&bl->priv->op_hash_mutex); if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) { g_warning ("conflicting ldap msgid's"); @@ -1161,6 +1162,7 @@ ldap_op_add (LDAPOp *op, LDAP_POLL_INTERVAL, (GSourceFunc) poll_ldap, bl); g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex); + g_static_rec_mutex_unlock (&eds_ldap_handler_lock); } static void @@ -1169,6 +1171,7 @@ ldap_op_finished (LDAPOp *op) EBookBackend *backend = op->backend; EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend); + g_static_rec_mutex_lock (&eds_ldap_handler_lock); g_static_rec_mutex_lock (&bl->priv->op_hash_mutex); g_hash_table_remove (bl->priv->id_to_op, &op->id); @@ -1176,10 +1179,8 @@ ldap_op_finished (LDAPOp *op) book_view_notify_status (bl, find_book_view (bl), ""); /* should handle errors here */ - g_static_rec_mutex_lock (&eds_ldap_handler_lock); if (bl->priv->ldap) ldap_abandon (bl->priv->ldap, op->id); - g_static_rec_mutex_unlock (&eds_ldap_handler_lock); if (op->dtor) op->dtor (op); @@ -1193,6 +1194,7 @@ ldap_op_finished (LDAPOp *op) } } g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex); + g_static_rec_mutex_unlock (&eds_ldap_handler_lock); } static void @@ -1202,6 +1204,7 @@ ldap_op_change_id (LDAPOp *op, EBookBackend *backend = op->backend; EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend); + g_static_rec_mutex_lock (&eds_ldap_handler_lock); g_static_rec_mutex_lock (&bl->priv->op_hash_mutex); g_hash_table_remove (bl->priv->id_to_op, &op->id); @@ -1209,6 +1212,7 @@ ldap_op_change_id (LDAPOp *op, g_hash_table_insert (bl->priv->id_to_op, &op->id, op); g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex); + g_static_rec_mutex_unlock (&eds_ldap_handler_lock); } static GError * @@ -5226,10 +5230,11 @@ ldap_cancel_op (gpointer key, LDAPOp *op = value; /* ignore errors, its only best effort? */ - g_static_rec_mutex_lock (&eds_ldap_handler_lock); + /* lock is held by the caller */ + /* g_static_rec_mutex_lock (&eds_ldap_handler_lock); */ if (bl->priv->ldap) ldap_abandon (bl->priv->ldap, op->id); - g_static_rec_mutex_unlock (&eds_ldap_handler_lock); + /* g_static_rec_mutex_unlock (&eds_ldap_handler_lock); */ } static void @@ -5237,9 +5242,11 @@ ldap_cancel_all_operations (EBookBackend *backend) { EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend); + g_static_rec_mutex_lock (&eds_ldap_handler_lock); g_static_rec_mutex_lock (&bl->priv->op_hash_mutex); g_hash_table_foreach (bl->priv->id_to_op, ldap_cancel_op, bl); g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex); + g_static_rec_mutex_unlock (&eds_ldap_handler_lock); } static void @@ -5533,10 +5540,11 @@ call_dtor (gint msgid, bl = E_BOOK_BACKEND_LDAP (op->backend); - g_static_rec_mutex_lock (&eds_ldap_handler_lock); + /* lock is held by the caller */ + /* g_static_rec_mutex_lock (&eds_ldap_handler_lock); */ if (bl->priv->ldap) ldap_abandon (bl->priv->ldap, op->id); - g_static_rec_mutex_unlock (&eds_ldap_handler_lock); + /* g_static_rec_mutex_unlock (&eds_ldap_handler_lock); */ op->dtor (op); @@ -5550,10 +5558,12 @@ e_book_backend_ldap_finalize (GObject *object) priv = E_BOOK_BACKEND_LDAP_GET_PRIVATE (object); + g_static_rec_mutex_lock (&eds_ldap_handler_lock); g_static_rec_mutex_lock (&priv->op_hash_mutex); g_hash_table_foreach_remove (priv->id_to_op, (GHRFunc) call_dtor, NULL); g_hash_table_destroy (priv->id_to_op); g_static_rec_mutex_unlock (&priv->op_hash_mutex); + g_static_rec_mutex_unlock (&eds_ldap_handler_lock); g_static_rec_mutex_free (&priv->op_hash_mutex); /* Remove the timeout before unbinding to avoid a race. */ |