-#ifdef BDB_PSEARCH
-
-#define is_sync_protocol(op) \
- ((op)->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST)
-
-#define IS_BDB_REPLACE(type) (( type == LDAP_PSEARCH_BY_DELETE ) || \
- ( type == LDAP_PSEARCH_BY_SCOPEOUT ))
-#define IS_PSEARCH (op != sop)
-#define IS_POST_SEARCH ( op->ors_post_search_id != NOID )
-
-static Operation *
-bdb_drop_psearch( Operation *op, ber_int_t msgid )
-{
- Operation *ps_list;
- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-
- LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- if ( ps_list->o_connid == op->o_connid ) {
- if ( ps_list->o_msgid == msgid ) {
- ps_list->o_abandon = 1;
- LDAP_LIST_REMOVE( ps_list, o_ps_link );
- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
- LDAP_STAILQ_REMOVE( &op->o_conn->c_ops, ps_list,
- slap_op, o_next );
- LDAP_STAILQ_NEXT( ps_list, o_next ) = NULL;
- op->o_conn->c_n_ops_executing--;
- op->o_conn->c_n_ops_completed++;
- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
- return ps_list;
- }
- }
- }
-
- return NULL;
-}
-
-int
-bdb_abandon( Operation *op, SlapReply *rs )
-{
- Operation *ps;
- void *saved_tmpmemctx;
-
- ps = bdb_drop_psearch( op, op->oq_abandon.rs_msgid );
- if ( ps ) {
- saved_tmpmemctx = ps->o_tmpmemctx;
-
- if (!BER_BVISNULL(&ps->o_req_dn)) {
- slap_sl_free(ps->o_req_dn.bv_val, ps->o_tmpmemctx );
- }
- if (!BER_BVISNULL(&ps->o_req_ndn)) {
- slap_sl_free(ps->o_req_ndn.bv_val, ps->o_tmpmemctx );
- }
- if (!BER_BVISNULL(&ps->ors_filterstr)) {
- ps->o_tmpfree(ps->ors_filterstr.bv_val, ps->o_tmpmemctx);
- }
- if (ps->ors_filter != NULL) {
- filter_free_x(ps, ps->ors_filter);
- }
- if (ps->ors_attrs != NULL) {
- ps->o_tmpfree(ps->ors_attrs, ps->o_tmpmemctx);
- }
-
- slap_op_free ( ps );
-
- if ( saved_tmpmemctx ) {
- slap_sl_mem_destroy( NULL, saved_tmpmemctx );
- }
-
- return LDAP_SUCCESS;
- }
- return LDAP_UNAVAILABLE;
-}
-
-int
-bdb_cancel( Operation *op, SlapReply *rs )
-{
- Operation *ps;
- void *saved_tmpmemctx;
-
- ps = bdb_drop_psearch( op, op->oq_cancel.rs_msgid );
- if ( ps ) {
- saved_tmpmemctx = ps->o_tmpmemctx;
-
- rs->sr_err = LDAP_CANCELLED;
- send_ldap_result( ps, rs );
-
- if (!BER_BVISNULL(&ps->o_req_dn)) {
- slap_sl_free(ps->o_req_dn.bv_val, ps->o_tmpmemctx );
- }
- if (!BER_BVISNULL(&ps->o_req_ndn)) {
- slap_sl_free(ps->o_req_ndn.bv_val, ps->o_tmpmemctx );
- }
- if (!BER_BVISNULL(&ps->ors_filterstr)) {
- ps->o_tmpfree(ps->ors_filterstr.bv_val, ps->o_tmpmemctx);
- }
- if (ps->ors_filter != NULL) {
- filter_free_x(ps, ps->ors_filter);
- }
- if (ps->ors_attrs != NULL) {
- ps->o_tmpfree(ps->ors_attrs, ps->o_tmpmemctx);
- }
-
- slap_op_free ( ps );
-
- if ( saved_tmpmemctx ) {
- slap_sl_mem_destroy( NULL, saved_tmpmemctx );
- }
-
- return LDAP_SUCCESS;
- }
- return LDAP_UNAVAILABLE;
-}
-
-int bdb_search( Operation *op, SlapReply *rs )
-{
- int rc;
- 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;
- }
- }
-
- op->o_ps_send_wait = NULL;
-
- 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;
- 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;
- }
-}
-#else
-int bdb_search( Operation *op, SlapReply *rs )
-{
- return bdb_do_search( op, rs, op, NULL, 0 );
-}
-#endif
-
-/* For persistent searches, op is the currently executing operation,
- * sop is the persistent search. For regular searches, sop = op.
- */