]> git.sur5r.net Git - openldap/commitdiff
In bdb_cache_add use a readlock outside the txn to protect the entry
authorHoward Chu <hyc@openldap.org>
Sat, 30 Dec 2006 12:05:55 +0000 (12:05 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 30 Dec 2006 12:05:55 +0000 (12:05 +0000)
until send_ldap_result completes.

servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/proto-bdb.h

index 41773376f099656bc2ffb438b2d3c65915a66e66..274c8f40df0d74ddc56db2da53039a630eabf239 100644 (file)
@@ -35,7 +35,7 @@ bdb_add(Operation *op, SlapReply *rs )
        DB_TXN          *ltid = NULL, *lt2;
        struct bdb_op_info opinfo = {0};
        int subentry;
-       u_int32_t       locker = 0;
+       u_int32_t       locker = 0, rlocker = 0;
        DB_LOCK         lock;
 
        int             num_retries = 0;
@@ -128,6 +128,9 @@ txnReturn:
                goto return_results;
        }
 
+       /* Get our thread locker ID */
+       rs->sr_err = LOCK_ID( bdb->bi_dbenv, &rlocker );
+
        if( 0 ) {
 retry: /* transaction retry */
                if( p ) {
@@ -424,7 +427,8 @@ retry:      /* transaction retry */
                        nrdn = op->ora_e->e_nname;
                }
 
-               bdb_cache_add( bdb, ei, op->ora_e, &nrdn, locker );
+               /* Use the thread locker here, outside the txn */
+               bdb_cache_add( bdb, ei, op->ora_e, &nrdn, rlocker, &lock );
 
                if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
                        rs->sr_text = "txn_commit failed";
@@ -461,27 +465,26 @@ return_results:
        }
        op->o_private = NULL;
 
-       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
-               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
-       }
-
        if( rs->sr_err == LDAP_SUCCESS ) {
-               EntryInfo *ei = oe->e_private;
-
                /* We own the entry now, and it can be purged at will
                 * Check to make sure it's the same entry we entered with.
                 * Possibly a callback may have mucked with it, although
                 * in general callbacks should treat the entry as read-only.
                 */
+               bdb_cache_return_entry_r( bdb->bi_dbenv, &bi->bi_cache, oe, &lock );
                if ( op->ora_e == oe )
                        op->ora_e = NULL;
-               ei->bei_state ^= CACHE_ENTRY_NOT_LINKED;
 
                if ( bdb->bi_txn_cp_kbyte ) {
                        TXN_CHECKPOINT( bdb->bi_dbenv,
                                bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
                }
        }
+
+       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
+               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
+               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
+       }
+
        return rs->sr_err;
 }
index 0c78cd393581a1a8189305db2d7df5900c9e20e6..7a652a6e7b8afaacaddd81581eded94aeee0a166 100644 (file)
@@ -886,10 +886,10 @@ bdb_cache_add(
        EntryInfo *eip,
        Entry *e,
        struct berval *nrdn,
-       u_int32_t locker )
+       u_int32_t locker,
+       DB_LOCK *lock )
 {
        EntryInfo *new, ei;
-       DB_LOCK lock;
        int rc;
 #ifdef BDB_HIER
        struct berval rdn = e->e_name;
@@ -903,7 +903,7 @@ bdb_cache_add(
        /* Lock this entry so that bdb_add can run to completion.
         * It can only fail if BDB has run out of lock resources.
         */
-       rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 1, 0, &lock );
+       rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 0, 0, lock );
        if ( rc ) {
                bdb_cache_entryinfo_unlock( eip );
                return rc;
@@ -931,9 +931,7 @@ bdb_cache_add(
        }
        new->bei_e = e;
        e->e_private = new;
-       /* Set "Not linked" status so LRU purger ignores it */
-       new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS |
-               CACHE_ENTRY_NOT_LINKED;
+       new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
        eip->bei_state &= ~CACHE_ENTRY_NO_KIDS;
        if (eip->bei_parent) {
                eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;
index cffda2426e210a9e532f3f3e917c74f52cca1642..98d840717d6648b438203b4ac635fb5033212a43 100644 (file)
@@ -499,7 +499,8 @@ int bdb_cache_add(
        EntryInfo *pei,
        Entry   *e,
        struct berval *nrdn,
-       u_int32_t locker
+       u_int32_t locker,
+       DB_LOCK *lock
 );
 int bdb_cache_modrdn(
        struct bdb_info *bdb,