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