]> git.sur5r.net Git - openldap/commitdiff
More for ITS#6961 - deadlock checking
authorHoward Chu <hyc@openldap.org>
Wed, 1 Jun 2011 18:29:39 +0000 (11:29 -0700)
committerHoward Chu <hyc@openldap.org>
Wed, 1 Jun 2011 18:29:39 +0000 (11:29 -0700)
servers/slapd/back-bdb/search.c

index b152c2b2966d41121c39a937443b8b41dd9a04df..cc41b963e1325e369ccf0228f4ae9826d3cee386 100644 (file)
@@ -313,7 +313,7 @@ sameido:
 /* Get the next ID from the DB. Used if the candidate list is
  * a range and simple iteration hits missing entryIDs
  */
-static ID
+static int
 bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
 {
        DBC *curs;
@@ -326,7 +326,7 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
        rc = bdb->bi_id2entry->bdi_db->cursor(
                bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags );
        if ( rc )
-               return NOID;
+               return rc;
        key.data = &nid;
        key.size = key.ulen = sizeof(ID);
        key.flags = DB_DBT_USERMEM;
@@ -335,9 +335,8 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
        rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
        curs->c_close( curs );
        if ( rc )
-               return NOID;
+               return rc;
        BDB_DISK2ID( &nid, cursor );
-       return *cursor;
 }
 
 int
@@ -747,6 +746,7 @@ fetch_entry_retry:
                                ltid->flags &= ~TXN_DEADLOCK;
                                goto fetch_entry_retry;
                        }
+txnfail:
                        opinfo->boi_err = rs->sr_err;
                        send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
                        goto done;
@@ -775,8 +775,25 @@ fetch_entry_retry:
                                        (long) id, 0, 0 );
                        } else {
                                /* get the next ID from the DB */
-                               id = bdb_get_nextid( bdb, ltid, &cursor );
-                               cursor = id - 1;
+id_retry:
+                               rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor );
+                               if ( rs->sr_err == DB_NOTFOUND ) {
+                                       break;
+                               } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
+                                       if ( opinfo )
+                                               goto txnfail;
+                                       ltid->flags &= ~TXN_DEADLOCK;
+                                       goto id_retry;
+                               } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) {
+                                       goto id_retry;
+                               }
+                               if ( rs->sr_err ) {
+                                       rs->sr_err = LDAP_OTHER;
+                                       rs->sr_text = "internal error in get_nextid";
+                                       send_ldap_result( op, rs );
+                                       goto done;
+                               }
+                               cursor--;
                        }
 
                        goto loop_continue;