]> git.sur5r.net Git - openldap/commitdiff
Must use txns everywhere, otherwise it will deadlock
authorHoward Chu <hyc@openldap.org>
Thu, 5 Mar 2009 21:59:05 +0000 (21:59 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 5 Mar 2009 21:59:05 +0000 (21:59 +0000)
servers/slapd/back-bdb/operational.c

index 86a475cc03bbfdcf4d734c6276c5cc4670c27c4b..4d71ce700195d9dc4fdb6d18b96aadddce3ecdf3 100644 (file)
@@ -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: