/* accept a connection on the socket */ static void *acceptconn(void *ctx, void *arg) { nssov_info *ni = arg; Connection conn = {0}; OperationBuffer opbuf; Operation *op; int csock; if ( slapd_shutdown ) return NULL; { struct sockaddr_storage addr; socklen_t alen; int j; /* accept a new connection */ alen=(socklen_t)sizeof(struct sockaddr_storage); csock=accept(ni->ni_socket,(struct sockaddr *)&addr,&alen); connection_client_enable(ni->ni_conn); if (csock<0) { if ((errno==EINTR)||(errno==EAGAIN)||(errno==EWOULDBLOCK)) { Debug( LDAP_DEBUG_TRACE,"nssov: accept() failed (ignored): %s",strerror(errno),0,0); return; } Debug( LDAP_DEBUG_ANY,"nssov: accept() failed: %s",strerror(errno),0,0); return; } /* make sure O_NONBLOCK is not inherited */ if ((j=fcntl(csock,F_GETFL,0))<0) { Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_GETFL) failed: %s",strerror(errno),0,0); if (close(csock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return; } if (fcntl(csock,F_SETFL,j&~O_NONBLOCK)<0) { Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_SETFL,~O_NONBLOCK) failed: %s",strerror(errno),0,0); if (close(csock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return; } } connection_fake_init( &conn, &opbuf, ctx ); op=&opbuf.ob_op; conn.c_ssf = conn.c_transport_ssf = local_ssf; op->o_bd = ni->ni_db; op->o_tag = LDAP_REQ_SEARCH; /* handle the connection */ handleconnection(ni,csock,op); }
void * asyncmeta_op_handle_result(void *ctx, void *arg) { a_metaconn_t *mc = arg; int i, j, rc, ntargets; struct timeval tv = {0}; LDAPMessage *msg; a_metasingleconn_t *msc; bm_context_t *bc; void *oldctx; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); rc = ++mc->mc_active; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if (rc > 1) return NULL; ntargets = mc->mc_info->mi_ntargets; i = ntargets; oldctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx, 0); /* get existing memctx */ again: for (j=0; j<ntargets; j++) { i++; if (i >= ntargets) i = 0; msc = &mc->mc_conns[i]; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); if (!mc->mc_conns[i].msc_ldr || META_BACK_CONN_CREATING( &mc->mc_conns[i] ) || META_BACK_CONN_INVALID(&mc->mc_conns[i])) { ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); continue; } msc->msc_active++; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); rc = ldap_result( mc->mc_conns[i].msc_ldr, LDAP_RES_ANY, LDAP_MSG_RECEIVED, &tv, &msg ); if (rc < 1) { if (rc < 0) { ldap_get_option( mc->mc_conns[i].msc_ldr, LDAP_OPT_ERROR_NUMBER, &rc); META_BACK_CONN_INVALID_SET(&mc->mc_conns[i]); asyncmeta_op_read_error(mc, i, rc, ctx); } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); msc->msc_active--; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); continue; } rc = ldap_msgtype( msg ); if (rc == LDAP_RES_BIND) { if ( LogTest( asyncmeta_debug ) ) { char time_buf[ SLAP_TEXT_BUFLEN ]; asyncmeta_get_timestamp(time_buf); Debug( asyncmeta_debug, "[%s] asyncmeta_op_handle_result received bind msgid=%d msc: %p\n", time_buf, ldap_msgid(msg), msc ); } asyncmeta_handle_bind_result(msg, mc, i, ctx); mc->mc_info->mi_targets[i]->mt_timeout_ops = 0; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); msc->msc_result_time = slap_get_time(); msc->msc_active--; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if (msg) ldap_msgfree(msg); continue; } retry_bc: ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); bc = asyncmeta_find_message(ldap_msgid(msg), mc, i); /* The sender might not be yet done with the context. On error it might also remove it * so it's best to try and find it again after a wait */ if (bc && bc->bc_active > 0) { ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); ldap_pvt_thread_yield(); goto retry_bc; } if (bc) { bc->bc_active++; } msc->msc_result_time = slap_get_time(); msc->msc_active--; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if (!bc) { Debug( asyncmeta_debug, "asyncmeta_op_handle_result: Unable to find bc for msguid %d, msc: %p\n", ldap_msgid(msg), msc ); ldap_msgfree(msg); continue; } /* set our memctx */ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); if (bc->op->o_abandon) { ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_drop_bc( mc, bc); if ( bc->op->o_tag == LDAP_REQ_SEARCH ) { int j; for (j=0; j<ntargets; j++) { if (bc->candidates[j].sr_msgid >= 0) { a_metasingleconn_t *tmp_msc = &mc->mc_conns[j]; tmp_msc->msc_active++; asyncmeta_back_cancel( mc, bc->op, bc->candidates[ j ].sr_msgid, j ); tmp_msc->msc_active--; } } } asyncmeta_clear_bm_context(bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if (msg) ldap_msgfree(msg); continue; } switch (rc) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_SEARCH_RESULT: case LDAP_RES_INTERMEDIATE: asyncmeta_handle_search_msg(msg, mc, bc, i); mc->mc_info->mi_targets[i]->mt_timeout_ops = 0; msg = NULL; break; case LDAP_RES_ADD: case LDAP_RES_DELETE: case LDAP_RES_MODDN: case LDAP_RES_COMPARE: case LDAP_RES_MODIFY: rc = asyncmeta_handle_common_result(msg, mc, bc, i); mc->mc_info->mi_targets[i]->mt_timeout_ops = 0; break; default: { Debug( asyncmeta_debug, "asyncmeta_op_handle_result: " "unrecognized response message tag=%d\n", rc ); } } if (msg) ldap_msgfree(msg); } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); rc = --mc->mc_active; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if (rc) { i++; goto again; } slap_sl_mem_setctx(ctx, oldctx); if (mc->mc_conns) { ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); for (i=0; i<ntargets; i++) { if (!slapd_shutdown && !META_BACK_CONN_INVALID(msc) && mc->mc_conns[i].msc_ldr && mc->mc_conns[i].conn) { connection_client_enable(mc->mc_conns[i].conn); } } ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); } return NULL; }