From: Jong Hyuk Choi Date: Thu, 11 Dec 2003 00:04:52 +0000 (+0000) Subject: fix for concurrent persistent searches X-Git-Tag: OPENLDAP_REL_ENG_2_1_MP~215 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=fa2aa5bb25e51ac72f946e62e3abc982a113b655;p=openldap fix for concurrent persistent searches --- diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 6159dcc0d5..a96e590161 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -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, diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 005b684516..a70cc05a4d 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -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; diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 3c36e56c05..439f938f07 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -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, diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 978fd5f0c4..1cb9b6fe98 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -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 diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 80bb20b0b6..087f9571a8 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -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, diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 39c6d3249a..50f0ad6143 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -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, diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index c0f9d4ac42..3d498b7e31 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -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 );