+ switch (ps_type) {
+ case LDAP_PSEARCH_BY_PREMODIFY:
+ case LDAP_PSEARCH_BY_PREDELETE:
+
+ 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;
+ }
+
+ /* Wait until refresh search send the entry */
+ while ( !pce->pc_sent ) {
+ if ( sop->o_refresh_in_progress ) {
+ ldap_pvt_thread_yield();
+ } else {
+ break;
+ }
+ }
+
+ if ( !sop->o_refresh_in_progress && !pce->pc_sent ) {
+ /* refresh ended without processing pce */
+ /* need to perform psearch for ps_e */
+ ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
+ LDAP_TAILQ_REMOVE( &sop->o_ps_pre_candidates, pce, pc_link );
+ ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
+ ch_free( pce );
+ rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
+ return rc;
+ } else {
+ /* the pce entry was sent in the refresh phase */
+ if ( ps_type == LDAP_PSEARCH_BY_PREMODIFY ) {
+ struct psid_entry* psid_e;
+ psid_e = (struct psid_entry *) ch_calloc(1,
+ sizeof(struct psid_entry));
+ psid_e->ps_op = sop;
+ LDAP_LIST_INSERT_HEAD( &op->o_pm_list, psid_e, ps_link );
+ }
+
+ ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
+ LDAP_TAILQ_REMOVE( &sop->o_ps_pre_candidates, pce, pc_link );
+ ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
+ ch_free( pce );
+ return LDAP_SUCCESS;
+ }
+ break;
+ case LDAP_PSEARCH_BY_DELETE:
+ case LDAP_PSEARCH_BY_SCOPEOUT:
+ case LDAP_PSEARCH_BY_ADD:
+ case LDAP_PSEARCH_BY_MODIFY:
+ ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
+ if ( sop->o_refresh_in_progress ||
+ !LDAP_TAILQ_EMPTY( &sop->o_ps_post_candidates )) {
+ pce = (struct pc_entry *) ch_calloc( 1, sizeof( struct pc_entry ));
+ pce->pc_id = ps_e->e_id;
+// pce->ps_type = ps_type;
+ ber_dupbv( &pce->pc_csn, &op->o_sync_csn );
+ if ( ps_type == LDAP_PSEARCH_BY_DELETE ) {
+ Attribute *a;
+ for ( a = ps_e->e_attrs; a != NULL; a = a->a_next ) {
+ AttributeDescription *desc = a->a_desc;
+ if ( desc == slap_schema.si_ad_entryUUID ) {
+ ber_dupbv( &pce->pc_entryUUID, &a->a_nvals[0] );
+ }
+ }
+ }
+ ber_dupbv( &pce->pc_ename, &ps_e->e_name );
+ ber_dupbv( &pce->pc_enname, &ps_e->e_nname );
+ LDAP_TAILQ_INSERT_TAIL( &sop->o_ps_post_candidates, pce, pc_link );
+ ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
+ } else {
+ ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
+ rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
+ return rc;
+ }
+ break;
+ default:
+ Debug( LDAP_DEBUG_TRACE, "do_psearch: invalid psearch type\n",
+ 0, 0, 0 );
+ return LDAP_OTHER;
+ }