]> git.sur5r.net Git - openldap/commitdiff
fix for concurrent persistent searches
authorJong Hyuk Choi <jongchoi@openldap.org>
Thu, 11 Dec 2003 00:04:52 +0000 (00:04 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Thu, 11 Dec 2003 00:04:52 +0000 (00:04 +0000)
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/search.c

index 6159dcc0d5ef0bde4555dc39c3da93ec9f9c988f..a96e590161e48c57f068e680cb69e24b982429c9 100644 (file)
@@ -497,6 +497,14 @@ retry:     /* transaction retry */
                                }
                        }
 
+                       if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
+                               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+                               LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                                       bdb_psearch( op, rs, ps_list, op->oq_add.rs_e, LDAP_PSEARCH_BY_ADD );
+                               }
+                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+                       }
+
                        if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
                                rs->sr_text = "txn_commit failed";
                        } else {
@@ -538,12 +546,6 @@ retry:     /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
-               LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
-                       bdb_psearch( op, rs, ps_list, op->oq_add.rs_e, LDAP_PSEARCH_BY_ADD );
-               }
-       }
-
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
                TXN_CHECKPOINT( bdb->bi_dbenv,
index 005b6845165fbb188c903bb92a38c6e25130ca97..a70cc05a4dc8844618ccbcd42b9c2ca798f4d0d2 100644 (file)
@@ -171,7 +171,7 @@ struct bdb_info {
        ID                      bi_lastid;
        ldap_pvt_thread_mutex_t bi_lastid_mutex;
        LDAP_LIST_HEAD(pl, slap_op) bi_psearch_list;
-       ldap_pvt_thread_mutex_t bi_pslist_mutex;
+       ldap_pvt_thread_rdwr_t bi_pslist_rwlock;
        LDAP_LIST_HEAD(se, slap_session_entry) bi_session_list;
 #ifdef SLAP_IDL_CACHE
        int             bi_idl_cache_max_size;
index 3c36e56c05a1cf795ff19c842838e1b3383c15a0..439f938f07ea156c372f028fe47e8c89c3c10b3b 100644 (file)
@@ -521,6 +521,14 @@ retry:     /* transaction retry */
                        }
                }
 
+               if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
+                       ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+                       LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                               bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE );
+                       }
+                       ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+               }
+
                rs->sr_err = TXN_COMMIT( ltid, 0 );
        }
        ltid = NULL;
@@ -560,12 +568,6 @@ retry:     /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
-               LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
-                       bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE );
-               }
-       }
-
        if(rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
                TXN_CHECKPOINT( bdb->bi_dbenv,
index 978fd5f0c4612c22a4d00822cef489e1494f128a..1cb9b6fe981f5749ba13cedbd0e7c9e1571bb646 100644 (file)
@@ -104,6 +104,7 @@ bdb_db_init( BackendDB *be )
 
        ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex );
        ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex );
+       ldap_pvt_thread_rdwr_init ( &bdb->bi_pslist_rwlock );
        ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_mutex );
        ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
        ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
@@ -548,6 +549,7 @@ bdb_db_destroy( BackendDB *be )
        ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
+       ldap_pvt_thread_rdwr_destroy ( &bdb->bi_pslist_rwlock );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
 #ifdef SLAP_IDL_CACHE
index 80bb20b0b64773006721f1d6d789d3495742eb06..087f9571a89b775b1f6cdc367ede65244b81a92e 100644 (file)
@@ -488,9 +488,11 @@ retry:     /* transaction retry */
        }
 
        if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
+               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch(op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
+               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
        }
 
        if( op->o_preread ) {
@@ -626,6 +628,24 @@ retry:     /* transaction retry */
                        }
                }
 
+               if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+                       /* Loop through in-scope entries for each psearch spec */
+                       ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+                       LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                               bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+                       }
+                       ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+                       pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
+                       while ( pm_list != NULL ) {
+                               bdb_psearch(op, rs, pm_list->ps_op,
+                                                       e, LDAP_PSEARCH_BY_SCOPEOUT);
+                               LDAP_LIST_REMOVE ( pm_list, ps_link );
+                               pm_prev = pm_list;
+                               pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
+                               ch_free( pm_prev );
+                       }
+               }
+
                rs->sr_err = TXN_COMMIT( ltid, 0 );
        }
        ltid = NULL;
@@ -667,22 +687,6 @@ retry:     /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
-               /* Loop through in-scope entries for each psearch spec */
-               LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
-                       bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
-               }
-               pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
-               while ( pm_list != NULL ) {
-                       bdb_psearch(op, rs, pm_list->ps_op,
-                                               e, LDAP_PSEARCH_BY_SCOPEOUT);
-                       LDAP_LIST_REMOVE ( pm_list, ps_link );
-                       pm_prev = pm_list;
-                       pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
-                       ch_free( pm_prev );
-               }
-       }
-
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
                TXN_CHECKPOINT( bdb->bi_dbenv,
index 39c6d3249ac35586eacbb38c9b89e13d0803be9f..50f0ad614326e48e2a7bf1598a14f487fc8030ac 100644 (file)
@@ -883,9 +883,11 @@ retry:     /* transaction retry */
        }
 
        if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
+               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
+               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
        }
 
        /* modify entry */
@@ -997,6 +999,24 @@ retry:     /* transaction retry */
                                }
                        }
 
+                       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+                               /* Loop through in-scope entries for each psearch spec */
+                               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+                               LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                                       bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+                               }
+                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+                               pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
+                               while ( pm_list != NULL ) {
+                                       bdb_psearch(op, rs, pm_list->ps_op,
+                                                               e, LDAP_PSEARCH_BY_SCOPEOUT);
+                                       pm_prev = pm_list;
+                                       LDAP_LIST_REMOVE ( pm_list, ps_link );
+                                       pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
+                                       ch_free( pm_prev );
+                               }
+                       }
+
                        if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
                                rs->sr_text = "txn_commit failed";
                        } else {
@@ -1036,22 +1056,6 @@ retry:   /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
-               /* Loop through in-scope entries for each psearch spec */
-               LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
-                       bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
-               }
-               pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
-               while ( pm_list != NULL ) {
-                       bdb_psearch(op, rs, pm_list->ps_op,
-                                               e, LDAP_PSEARCH_BY_SCOPEOUT);
-                       pm_prev = pm_list;
-                       LDAP_LIST_REMOVE ( pm_list, ps_link );
-                       pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
-                       ch_free( pm_prev );
-               }
-       }
-
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
                TXN_CHECKPOINT( bdb->bi_dbenv,
index c0f9d4ac42854fb747a45c849a097a0931b00954..3d498b7e31319e873e65687342f78c195a664713 100644 (file)
@@ -437,12 +437,12 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        /* psearch needs to be registered before refresh begins */
        /* psearch and refresh transmission is serialized in send_ldap_ber() */
        if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
-               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+               ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
                LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link );
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
        } else if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST
                                && sop->o_sync_slog_size >= 0 ) {
-               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+               ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
                LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        if ( ps_list->o_sync_slog_size >= 0 ) {
                                if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) {
@@ -476,7 +476,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
                } else {
                        sop->o_sync_state.sid = -1;
                }
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
        }
 
        null_attr.an_desc = NULL;
@@ -733,19 +733,23 @@ dn2entry_retry:
        }
        e = NULL;
 
-       rs->sr_err = bdb_get_commit_csn( sop, rs, &search_context_csn, locker, &ctxcsn_lock );
+       if ( !IS_PSEARCH ) {
+               rs->sr_err = bdb_get_commit_csn( sop, rs, &search_context_csn, locker, &ctxcsn_lock );
 
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               send_ldap_error( sop, rs, rs->sr_err, "error in csn management in search" );
-               goto done;
-       }
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       send_ldap_error( sop, rs, rs->sr_err, "error in csn management in search" );
+                       goto done;
+               }
 
-       if ( sop->o_sync_mode != SLAP_SYNC_NONE && sop->o_sync_state.ctxcsn &&
-                sop->o_sync_state.ctxcsn->bv_val &&
-                ber_bvcmp( &sop->o_sync_state.ctxcsn[0], search_context_csn ) == 0 )
-       {
-               bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock );
-               goto nochange;
+               if ( sop->o_sync_mode != SLAP_SYNC_NONE && sop->o_sync_state.ctxcsn &&
+                        sop->o_sync_state.ctxcsn->bv_val &&
+                        ber_bvcmp( &sop->o_sync_state.ctxcsn[0], search_context_csn ) == 0 )
+               {
+                       bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock );
+                       goto nochange;
+               }
+       } else {
+               search_context_csn = ber_dupbv( NULL, &op->o_sync_csn );        
        }
 
        /* select candidates */
@@ -758,8 +762,10 @@ dn2entry_retry:
                rs->sr_err = search_candidates( op, sop, rs, &base, locker, candidates, scopes );
        }
 
-       if ( sop->o_sync_mode != SLAP_SYNC_NONE ) {
-               bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock );
+       if ( !IS_PSEARCH ) {
+               if ( sop->o_sync_mode != SLAP_SYNC_NONE ) {
+                       bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock );
+               }
        }
 
        /* start cursor at beginning of candidates.
@@ -1406,7 +1412,7 @@ nochange:
                                } else {
                                        if ( !no_sync_state_change ) {
                                                int slog_found = 0;
-                                               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+                                               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                                                LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                                                        if ( ps_list->o_sync_slog_size > 0 ) {
                                                                if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) {
@@ -1422,7 +1428,7 @@ nochange:
                                                        rs->sr_ctrls = NULL;
                                                        slap_send_session_log( op, ps_list, rs );
                                                }
-                                               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+                                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
                                        }
                                        rs->sr_err = LDAP_SUCCESS;
                                        rs->sr_rspoid = LDAP_SYNC_INFO;
@@ -1448,7 +1454,7 @@ nochange:
                                } else {
                                        if ( !no_sync_state_change ) {
                                                int slog_found = 0;
-                                               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+                                               ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                                                LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list,
                                                                o_ps_link ) {
                                                        if ( ps_list->o_sync_slog_size > 0 ) {
@@ -1463,7 +1469,7 @@ nochange:
                                                if ( slog_found ) {
                                                        slap_send_session_log( op, ps_list, rs );
                                                }
-                                               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+                                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
                                        }
                                        slap_build_sync_done_ctrl( sop, rs, ctrls,
                                                num_ctrls++, 1, &cookie, LDAP_SYNC_REFRESH_DELETES );