From 53c40fac27657bdf09d4fb4d132976c3473a1edd Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 11 Feb 2006 17:40:28 +0000 Subject: [PATCH] rework connection handling on multiple binds with the same connection --- servers/slapd/back-meta/back-meta.h | 7 +++- servers/slapd/back-meta/bind.c | 4 +-- servers/slapd/back-meta/conn.c | 50 ++++++++++++++++++++--------- servers/slapd/back-meta/unbind.c | 9 ++---- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index c4c69759e1..76e68f4af6 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -371,7 +371,12 @@ meta_back_conn_cmp( const void *c2 ); extern int -meta_back_conn_dup( +meta_back_dnconn_cmp( + const void *c1, + const void *c2 ); + +extern int +meta_back_dnconn_dup( void *c1, void *c2 ); diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 0540c23ec3..9f5c0962da 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -205,12 +205,12 @@ retry_lock:; assert( mc->mc_refcnt == 1 ); mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, - meta_back_conn_cmp ); + meta_back_dnconn_cmp ); assert( mc != NULL ); ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn ); lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc, - meta_back_conn_cmp, meta_back_conn_dup ); + meta_back_dnconn_cmp, meta_back_dnconn_dup ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); if ( lerr == -1 ) { for ( i = 0; i < mi->mi_ntargets; ++i ) { diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 46e5d20a0a..640a7ca16c 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -40,13 +40,13 @@ #define PRINT_CONNTREE 0 /* - * meta_back_conn_cmp + * meta_back_dnconn_cmp * - * compares two struct metaconn based on the value of the conn pointer; - * used by avl stuff + * compares two struct metaconn based on the value of the conn pointer + * and of the local DN; used by avl stuff */ int -meta_back_conn_cmp( +meta_back_dnconn_cmp( const void *c1, const void *c2 ) { @@ -55,11 +55,31 @@ meta_back_conn_cmp( int rc; /* If local DNs don't match, it is definitely not a match */ - rc = ber_bvcmp( &mc1->mc_local_ndn, &mc2->mc_local_ndn ); - if ( rc ) { - return rc; + /* For shared sessions, conn is NULL. Only explicitly + * bound sessions will have non-NULL conn. + */ + rc = SLAP_PTRCMP( mc1->mc_conn, mc2->mc_conn ); + if ( rc == 0 ) { + rc = ber_bvcmp( &mc1->mc_local_ndn, &mc2->mc_local_ndn ); } + return rc; +} + +/* + * meta_back_conn_cmp + * + * compares two struct metaconn based on the value of the conn pointer; + * used by avl stuff + */ +int +meta_back_conn_cmp( + const void *c1, + const void *c2 ) +{ + metaconn_t *mc1 = ( metaconn_t * )c1; + metaconn_t *mc2 = ( metaconn_t * )c2; + /* For shared sessions, conn is NULL. Only explicitly * bound sessions will have non-NULL conn. */ @@ -67,13 +87,13 @@ meta_back_conn_cmp( } /* - * meta_back_conn_dup + * meta_back_dnconn_dup * * returns -1 in case a duplicate struct metaconn has been inserted; * used by avl stuff */ int -meta_back_conn_dup( +meta_back_dnconn_dup( void *c1, void *c2 ) { @@ -81,8 +101,8 @@ meta_back_conn_dup( metaconn_t *mc2 = ( metaconn_t * )c2; /* Cannot have more than one shared session with same DN */ - if ( dn_match( &mc1->mc_local_ndn, &mc2->mc_local_ndn ) && - mc1->mc_conn == mc2->mc_conn ) + if ( mc1->mc_conn == mc2->mc_conn && + dn_match( &mc1->mc_local_ndn, &mc2->mc_local_ndn ) ) { return -1; } @@ -790,7 +810,7 @@ meta_back_getconn( 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 ); + (caddr_t)&mc_curr, meta_back_dnconn_cmp ); if ( mc ) { if ( mc->mc_tainted ) { rs->sr_err = LDAP_UNAVAILABLE; @@ -992,7 +1012,7 @@ retry_lock: 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 ); + (caddr_t)&mc_curr, meta_back_dnconn_cmp ); if ( mc != NULL ) { mc->mc_refcnt++; } @@ -1158,7 +1178,7 @@ done:; */ ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, - meta_back_conn_cmp, meta_back_conn_dup ); + meta_back_dnconn_cmp, meta_back_dnconn_dup ); #if PRINT_CONNTREE > 0 myprint( mi->mi_conninfo.lai_tree ); @@ -1218,7 +1238,7 @@ meta_back_release_conn( 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 ); + meta_back_dnconn_cmp ); meta_back_conn_free( mc ); } ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); diff --git a/servers/slapd/back-meta/unbind.c b/servers/slapd/back-meta/unbind.c index 6b08b50a7c..0b301a242c 100644 --- a/servers/slapd/back-meta/unbind.c +++ b/servers/slapd/back-meta/unbind.c @@ -49,14 +49,10 @@ meta_back_conn_destroy( BER_BVISNULL( &conn->c_ndn ) ? "" : conn->c_ndn.bv_val, 0 ); mc_curr.mc_conn = conn; - mc_curr.mc_local_ndn = conn->c_ndn; ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); - mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, - meta_back_conn_cmp ); - ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); - - if ( mc ) { + while ( ( mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, meta_back_conn_cmp ) ) != NULL ) + { Debug( LDAP_DEBUG_TRACE, "=>meta_back_conn_destroy: destroying conn %ld\n", LDAP_BACK_PCONN_ID( mc->mc_conn ), 0, 0 ); @@ -65,6 +61,7 @@ meta_back_conn_destroy( meta_back_conn_free( mc ); } + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); /* * Cleanup rewrite session -- 2.39.5