fix for concurrent persistent searches

This commit is contained in:
Jong Hyuk Choi 2003-12-11 00:04:52 +00:00
parent 2aca8de6b3
commit fa2aa5bb25
7 changed files with 86 additions and 66 deletions

View 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,

View 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;

View 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,

View 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

View 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,

View 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,

View 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 );