ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
- ldapconn_t *lc,
+ ldapconn_t *lc = NULL,
lc_curr = { 0 };
int refcnt = 1;
}
/* Explicit Bind requests always get their own conn */
- if ( sendok & LDAP_BACK_BINDING ) {
- lc = NULL;
- } else {
+ if ( !( sendok & LDAP_BACK_BINDING ) ) {
/* Searches for a ldapconn in the avl tree */
retry_lock:
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
(caddr_t)&lc_curr, ldap_back_conn_cmp );
if ( lc != NULL ) {
- refcnt = ++lc->lc_refcnt;
/* Don't reuse connections while they're still binding */
- if ( LDAP_BACK_CONN_BINDING( lc )) {
+ if ( LDAP_BACK_CONN_BINDING( lc ) ) {
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
ldap_pvt_thread_yield();
goto retry_lock;
}
+ refcnt = ++lc->lc_refcnt;
}
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
}
if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
return NULL;
}
- if ( sendok & LDAP_BACK_BINDING )
+ if ( sendok & LDAP_BACK_BINDING ) {
LDAP_BACK_CONN_BINDING_SET( lc );
-
+ }
lc->lc_conn = lc_curr.lc_conn;
ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
}
}
- /* Searches for a metaconn in the avl tree */
- ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
- mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
- (caddr_t)&mc_curr, meta_back_conn_cmp );
- if ( mc ) {
- if ( mc->mc_tainted ) {
- rs->sr_err = LDAP_UNAVAILABLE;
- rs->sr_text = "remote server unavailable";
- ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
- return NULL;
- }
+ /* Explicit Bind requests always get their own conn */
+ if ( !( sendok & LDAP_BACK_BINDING ) ) {
+ /* Searches for a metaconn in the avl tree */
+retry_lock:
+ ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+ mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
+ (caddr_t)&mc_curr, meta_back_conn_cmp );
+ if ( mc ) {
+ if ( mc->mc_tainted ) {
+ rs->sr_err = LDAP_UNAVAILABLE;
+ rs->sr_text = "remote server unavailable";
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+ return NULL;
+ }
- mc->mc_refcnt++;
+ /* Don't reuse connections while they're still binding */
+ if ( LDAP_BACK_CONN_BINDING( mc ) ) {
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+ }
+ mc->mc_refcnt++;
+ }
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
- ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
switch ( op->o_tag ) {
case LDAP_REQ_ADD:
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
+ if ( sendok & LDAP_BACK_BINDING ) {
+ LDAP_BACK_CONN_BINDING_SET( mc );
+ }
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
/* Retries searching for a metaconn in the avl tree
* the reason is that the connection might have been
* created by meta_back_get_candidate() */
- ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
- mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
- (caddr_t)&mc_curr, meta_back_conn_cmp );
- if ( mc != NULL ) {
- mc->mc_refcnt++;
+ if ( !( sendok & LDAP_BACK_BINDING ) ) {
+ ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+ mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
+ (caddr_t)&mc_curr, meta_back_conn_cmp );
+ if ( mc != NULL ) {
+ mc->mc_refcnt++;
+ }
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
- ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
/* Looks like we didn't get a bind. Open a new session... */
if ( mc == NULL ) {
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
+ if ( sendok & LDAP_BACK_BINDING ) {
+ LDAP_BACK_CONN_BINDING_SET( mc );
+ }
}
}
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
+ if ( sendok & LDAP_BACK_BINDING ) {
+ LDAP_BACK_CONN_BINDING_SET( mc );
+ }
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
assert( mc->mc_refcnt > 0 );
mc->mc_refcnt--;
+ LDAP_BACK_CONN_BINDING_CLEAR( mc );
if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
(void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
meta_back_conn_cmp );