- struct pc_entry *pce = NULL;
- struct pc_entry *tmp_pce = NULL;
- Entry ps_e = {0};
- Attribute *a;
-
- ps_e.e_private = NULL;
- ldap_pvt_thread_mutex_init( &op->o_pcmutex );
- LDAP_TAILQ_INIT( &op->o_ps_pre_candidates );
- LDAP_TAILQ_INIT( &op->o_ps_post_candidates );
-
- op->ors_post_search_id = NOID;
- rc = bdb_do_search( op, rs, op, NULL, 0 );
-
- ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
- pce = LDAP_TAILQ_FIRST( &op->o_ps_post_candidates );
- ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
-
- while ( rc == LDAP_SUCCESS && pce &&
- op->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
-
- ps_e.e_id = op->ors_post_search_id = pce->pc_id;
- if ( op->o_sync_csn.bv_val ) {
- ch_free( op->o_sync_csn.bv_val );
- op->o_sync_csn.bv_val = NULL;
- }
- ber_dupbv( &op->o_sync_csn, &pce->pc_csn );
- ber_dupbv( &ps_e.e_name, &pce->pc_ename );
- ber_dupbv( &ps_e.e_nname, &pce->pc_enname );
- a = ch_calloc( 1, sizeof( Attribute ));
- a->a_desc = slap_schema.si_ad_entryUUID;
- a->a_vals = ch_calloc( 2, sizeof( struct berval ));
- ber_dupbv( &a->a_vals[0], &pce->pc_entryUUID );
- a->a_nvals = a->a_vals;
- a->a_next = NULL;
- ps_e.e_attrs = a;
-
- rc = bdb_do_search( op, rs, op, &ps_e, 0 );
-
- tmp_pce = pce;
- ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
- pce = LDAP_TAILQ_NEXT( pce, pc_link );
- LDAP_TAILQ_REMOVE( &op->o_ps_post_candidates, tmp_pce, pc_link );
- ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
-
- ch_free( tmp_pce->pc_csn.bv_val );
- ch_free( tmp_pce->pc_entryUUID.bv_val );
- ch_free( tmp_pce->pc_ename.bv_val );
- ch_free( tmp_pce->pc_enname.bv_val );
- ch_free( tmp_pce );
- entry_clean( &ps_e );
- }
- return rc;
-}
-
-#define BDB_PSEARCH_MAX_WAIT 3
-int bdb_psearch( Operation *op, SlapReply *rs, Operation *sop,
- Entry *ps_e, int ps_type )
-{
- int rc;
- struct pc_entry *pce = NULL;
- struct pc_entry *p = NULL;
- int num_retries = 0;
-
- op->ors_post_search_id = NOID;
-
- switch (ps_type) {
- case LDAP_PSEARCH_BY_PREMODIFY:
- case LDAP_PSEARCH_BY_PREDELETE:
-
- if ( !op->o_ps_send_wait ) {
- if ( sop->o_refresh_in_progress ) {
- pce = (struct pc_entry *) ch_calloc(
- 1, sizeof( struct pc_entry ));
- pce->pc_id = ps_e->e_id;
- ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
- if ( LDAP_TAILQ_EMPTY( &sop->o_ps_pre_candidates )) {
- LDAP_TAILQ_INSERT_HEAD(
- &sop->o_ps_pre_candidates, pce, pc_link );
- } else {
- LDAP_TAILQ_FOREACH( p,
- &sop->o_ps_pre_candidates, pc_link ) {
- if ( p->pc_id > pce->pc_id )
- break;
- }
-
- if ( p ) {
- LDAP_TAILQ_INSERT_BEFORE( p, pce, pc_link );
- } else {
- LDAP_TAILQ_INSERT_TAIL(
- &sop->o_ps_pre_candidates,
- pce, pc_link );
- }
- }
- ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
- } else {
- rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
- return rc;
- }
- } else {
- pce = op->o_ps_send_wait;
- }
-
- /* Wait until refresh search send the entry */
- while ( !pce->pc_sent ) {
- if ( sop->o_refresh_in_progress ) {
- if ( num_retries == BDB_PSEARCH_MAX_WAIT ) {
- op->o_ps_send_wait = pce;
- return LDAP_BUSY;
- }
- ldap_pvt_thread_yield();
- bdb_trans_backoff( ++num_retries );
- } else {
- break;
- }
- }