static meta_search_candidate_t asyncmeta_send_pending_op(bm_context_t *bc, int candidate) { meta_search_candidate_t retcode; switch (bc->op->o_tag) { case LDAP_REQ_SEARCH: retcode = asyncmeta_back_search_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, NULL, 0 , 0); break; case LDAP_REQ_ADD: retcode = asyncmeta_back_add_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0); break; case LDAP_REQ_MODIFY: retcode = asyncmeta_back_modify_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0); break; case LDAP_REQ_MODRDN: retcode = asyncmeta_back_modrdn_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0); break; case LDAP_REQ_COMPARE: retcode = asyncmeta_back_compare_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0); break; case LDAP_REQ_DELETE: retcode = asyncmeta_back_delete_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0); break; default: retcode = META_SEARCH_NOT_CANDIDATE; } return retcode; }
int asyncmeta_back_add( Operation *op, SlapReply *rs ) { a_metainfo_t *mi = ( a_metainfo_t * )op->o_bd->be_private; a_metatarget_t *mt; a_metaconn_t *mc; int rc, candidate = -1; OperationBuffer opbuf; bm_context_t *bc; SlapReply *candidates; slap_callback *cb = op->o_callback; Debug(LDAP_DEBUG_ARGS, "==> asyncmeta_back_add: %s\n", op->o_req_dn.bv_val, 0, 0 ); asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets ); if (bc == NULL) { rs->sr_err = LDAP_OTHER; asyncmeta_sender_error(op, rs, cb); return rs->sr_err; } candidates = bc->candidates; mc = asyncmeta_getconn( op, rs, candidates, &candidate, LDAP_BACK_DONTSEND, 0); if ( !mc || rs->sr_err != LDAP_SUCCESS) { asyncmeta_sender_error(op, rs, cb); asyncmeta_clear_bm_context(bc); return rs->sr_err; } mt = mi->mi_targets[ candidate ]; bc->timeout = mt->mt_timeout[ SLAP_OP_ADD ]; bc->retrying = LDAP_BACK_RETRYING; bc->sendok = ( LDAP_BACK_SENDRESULT | bc->retrying ); bc->stoptime = op->o_time + bc->timeout; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); rc = asyncmeta_add_message_queue(mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); if (rc != LDAP_SUCCESS) { rs->sr_err = LDAP_BUSY; rs->sr_text = "Maximum pending ops limit exceeded"; asyncmeta_clear_bm_context(bc); asyncmeta_sender_error(op, rs, cb); goto finish; } rc = asyncmeta_dobind_init_with_retry(op, rs, bc, mc, candidate); switch (rc) { case META_SEARCH_CANDIDATE: /* target is already bound, just send the request */ Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: " "cnd=\"%ld\"\n", op->o_log_prefix, candidate , 0); rc = asyncmeta_back_add_start( op, rs, mc, bc, candidate); if (rc == META_SEARCH_ERR) { ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); asyncmeta_drop_bc(mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); asyncmeta_sender_error(op, rs, cb); asyncmeta_clear_bm_context(bc); goto finish; } break; case META_SEARCH_NOT_CANDIDATE: Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: NOT_CANDIDATE " "cnd=\"%ld\"\n", op->o_log_prefix, candidate , 0); candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); asyncmeta_drop_bc(mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); asyncmeta_sender_error(op, rs, cb); asyncmeta_clear_bm_context(bc); goto finish; case META_SEARCH_NEED_BIND: case META_SEARCH_CONNECTING: Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: NEED_BIND " "cnd=\"%ld\" %p\n", op->o_log_prefix, candidate , &mc->mc_conns[candidate]); rc = asyncmeta_dobind_init(op, rs, bc, mc, candidate); if (rc == META_SEARCH_ERR) { ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); asyncmeta_drop_bc(mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); asyncmeta_sender_error(op, rs, cb); asyncmeta_clear_bm_context(bc); goto finish; } break; case META_SEARCH_BINDING: Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: BINDING " "cnd=\"%ld\" %p\n", op->o_log_prefix, candidate , &mc->mc_conns[candidate]); /* Todo add the context to the message queue but do not send the request the receiver must send this when we are done binding */ /* question - how would do receiver know to which targets??? */ break; case META_SEARCH_ERR: Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: ERR " "cnd=\"%ldd\"\n", op->o_log_prefix, candidate , 0); candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; candidates[ candidate ].sr_type = REP_RESULT; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); asyncmeta_drop_bc(mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); asyncmeta_sender_error(op, rs, cb); asyncmeta_clear_bm_context(bc); goto finish; default: assert( 0 ); break; } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex); asyncmeta_start_one_listener(mc, candidates, bc, candidate); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); finish: return rs->sr_err; }