From cf5c0e1da96c82886119b4038dbeff254b38eaa2 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Thu, 5 Mar 2009 23:24:28 +0000
Subject: [PATCH] Once more, mutex_lock -> trylock... Must use txns everywhere,
 otherwise it will deadlock

---
 servers/slapd/back-bdb/operational.c | 21 +++++++++++++++++++--
 servers/slapd/syncrepl.c             |  7 +++++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c
index 86a475cc03..4d71ce7001 100644
--- a/servers/slapd/back-bdb/operational.c
+++ b/servers/slapd/back-bdb/operational.c
@@ -34,6 +34,10 @@ bdb_hasSubordinates(
 	Entry		*e,
 	int		*hasSubordinates )
 {
+	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+	struct bdb_op_info	*opinfo;
+	OpExtra *oex;
+	DB_TXN		*rtxn;
 	int		rc;
 	
 	assert( e != NULL );
@@ -47,12 +51,25 @@ bdb_hasSubordinates(
 		return LDAP_OTHER;
 	}
 
+	/* Check for a txn in a parent op, otherwise use reader txn */
+	LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
+		if ( oex->oe_key == bdb )
+			break;
+	}
+	opinfo = (struct bdb_op_info *) oex;
+	if ( opinfo && opinfo->boi_txn ) {
+		rtxn = opinfo->boi_txn;
+	} else {
+		rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
+		if ( rc ) return LDAP_OTHER;
+	}
+
 retry:
 	/* FIXME: we can no longer assume the entry's e_private
 	 * field is correctly populated; so we need to reacquire
 	 * it with reader lock */
-	rc = bdb_cache_children( op, NULL, e );
-	
+	rc = bdb_cache_children( op, rtxn, e );
+
 	switch( rc ) {
 	case DB_LOCK_DEADLOCK:
 	case DB_LOCK_NOTGRANTED:
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 8511fc4dda..7ad5c813ab 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -1258,8 +1258,11 @@ do_syncrepl(
 	if ( si == NULL )
 		return NULL;
 
-	/* There will never be more than one instance active */
-	ldap_pvt_thread_mutex_lock( &si->si_mutex );
+	/* Don't get stuck here while a pause is initiated */
+	while ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
+		if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool ))
+			ldap_pvt_thread_yield();
+	}
 
 	switch( abs( si->si_type ) ) {
 	case LDAP_SYNC_REFRESH_ONLY:
-- 
GitLab