mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
fix potential deadlock; first round of refcnt for connections
This commit is contained in:
parent
982981d465
commit
9146b262ad
@ -177,6 +177,7 @@ typedef struct metasingleconn_t {
|
|||||||
typedef struct metaconn_t {
|
typedef struct metaconn_t {
|
||||||
struct slap_conn *mc_conn;
|
struct slap_conn *mc_conn;
|
||||||
ldap_pvt_thread_mutex_t mc_mutex;
|
ldap_pvt_thread_mutex_t mc_mutex;
|
||||||
|
unsigned mc_refcnt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* means that the connection is bound;
|
* means that the connection is bound;
|
||||||
@ -186,7 +187,10 @@ typedef struct metaconn_t {
|
|||||||
#define META_BOUND_NONE (-1)
|
#define META_BOUND_NONE (-1)
|
||||||
#define META_BOUND_ALL (-2)
|
#define META_BOUND_ALL (-2)
|
||||||
/* supersedes the connection stuff */
|
/* supersedes the connection stuff */
|
||||||
metasingleconn_t *mc_conns;
|
metasingleconn_t mc_conns[ 1 ];
|
||||||
|
/* NOTE: mc_conns must be last, because
|
||||||
|
* the required number of conns is malloc'ed
|
||||||
|
* in one block with the metaconn_t structure */
|
||||||
} metaconn_t;
|
} metaconn_t;
|
||||||
|
|
||||||
typedef struct metatarget_t {
|
typedef struct metatarget_t {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <ac/errno.h>
|
||||||
#include <ac/socket.h>
|
#include <ac/socket.h>
|
||||||
#include <ac/string.h>
|
#include <ac/string.h>
|
||||||
|
|
||||||
@ -136,8 +137,6 @@ metaconn_alloc(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc->mc_conns = ( metasingleconn_t * )&mc[ 1 ];
|
|
||||||
|
|
||||||
for ( i = 0; i < ntargets; i++ ) {
|
for ( i = 0; i < ntargets; i++ ) {
|
||||||
mc->mc_conns[ i ].msc_ld = NULL;
|
mc->mc_conns[ i ].msc_ld = NULL;
|
||||||
BER_BVZERO( &mc->mc_conns[ i ].msc_bound_ndn );
|
BER_BVZERO( &mc->mc_conns[ i ].msc_bound_ndn );
|
||||||
@ -148,6 +147,7 @@ metaconn_alloc(
|
|||||||
|
|
||||||
mc->mc_auth_target = META_BOUND_NONE;
|
mc->mc_auth_target = META_BOUND_NONE;
|
||||||
ldap_pvt_thread_mutex_init( &mc->mc_mutex );
|
ldap_pvt_thread_mutex_init( &mc->mc_mutex );
|
||||||
|
mc->mc_refcnt = 1;
|
||||||
|
|
||||||
return mc;
|
return mc;
|
||||||
}
|
}
|
||||||
@ -626,7 +626,16 @@ meta_back_getconn(
|
|||||||
|
|
||||||
/* Searches for a metaconn in the avl tree */
|
/* Searches for a metaconn in the avl tree */
|
||||||
mc_curr.mc_conn = op->o_conn;
|
mc_curr.mc_conn = op->o_conn;
|
||||||
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
|
retry_lock:;
|
||||||
|
switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
|
||||||
|
case LDAP_PVT_THREAD_EBUSY:
|
||||||
|
default:
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
|
goto retry_lock;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
mc = (metaconn_t *)avl_find( mi->mi_conntree,
|
mc = (metaconn_t *)avl_find( mi->mi_conntree,
|
||||||
(caddr_t)&mc_curr, meta_back_conn_cmp );
|
(caddr_t)&mc_curr, meta_back_conn_cmp );
|
||||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
||||||
@ -786,7 +795,16 @@ meta_back_getconn(
|
|||||||
|
|
||||||
/* Retries searching for a metaconn in the avl tree */
|
/* Retries searching for a metaconn in the avl tree */
|
||||||
mc_curr.mc_conn = op->o_conn;
|
mc_curr.mc_conn = op->o_conn;
|
||||||
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
|
retry_lock2:;
|
||||||
|
switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
|
||||||
|
case LDAP_PVT_THREAD_EBUSY:
|
||||||
|
default:
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
|
goto retry_lock2;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
mc = (metaconn_t *)avl_find( mi->mi_conntree,
|
mc = (metaconn_t *)avl_find( mi->mi_conntree,
|
||||||
(caddr_t)&mc_curr, meta_back_conn_cmp );
|
(caddr_t)&mc_curr, meta_back_conn_cmp );
|
||||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
||||||
@ -810,12 +828,7 @@ meta_back_getconn(
|
|||||||
*/
|
*/
|
||||||
err = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
|
err = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
|
||||||
&mc->mc_conns[ i ], sendok );
|
&mc->mc_conns[ i ], sendok );
|
||||||
if ( err == LDAP_SUCCESS ) {
|
if ( err != LDAP_SUCCESS ) {
|
||||||
candidates[ i ].sr_tag = META_CANDIDATE;
|
|
||||||
ncandidates++;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: in case one target cannot
|
* FIXME: in case one target cannot
|
||||||
* be init'd, should the other ones
|
* be init'd, should the other ones
|
||||||
@ -829,6 +842,9 @@ meta_back_getconn(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
candidates[ i ].sr_tag = META_CANDIDATE;
|
||||||
|
ncandidates++;
|
||||||
|
|
||||||
if ( candidate ) {
|
if ( candidate ) {
|
||||||
*candidate = i;
|
*candidate = i;
|
||||||
}
|
}
|
||||||
@ -923,7 +939,16 @@ done:;
|
|||||||
/*
|
/*
|
||||||
* Inserts the newly created metaconn in the avl tree
|
* Inserts the newly created metaconn in the avl tree
|
||||||
*/
|
*/
|
||||||
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
|
retry_lock3:;
|
||||||
|
switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
|
||||||
|
case LDAP_PVT_THREAD_EBUSY:
|
||||||
|
default:
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
|
goto retry_lock3;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
err = avl_insert( &mi->mi_conntree, ( caddr_t )mc,
|
err = avl_insert( &mi->mi_conntree, ( caddr_t )mc,
|
||||||
meta_back_conn_cmp, meta_back_conn_dup );
|
meta_back_conn_cmp, meta_back_conn_dup );
|
||||||
|
|
||||||
@ -936,12 +961,7 @@ done:;
|
|||||||
/*
|
/*
|
||||||
* Err could be -1 in case a duplicate metaconn is inserted
|
* Err could be -1 in case a duplicate metaconn is inserted
|
||||||
*/
|
*/
|
||||||
if ( err == 0 ) {
|
if ( err != 0 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
|
|
||||||
op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
Debug( LDAP_DEBUG_ANY,
|
||||||
"%s meta_back_getconn: candidates=%d conn=%ld insert failed\n",
|
"%s meta_back_getconn: candidates=%d conn=%ld insert failed\n",
|
||||||
op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
|
op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
|
||||||
@ -956,6 +976,10 @@ done:;
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
|
||||||
|
op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"%s meta_back_getconn: candidates=%d conn=%ld fetched\n",
|
"%s meta_back_getconn: candidates=%d conn=%ld fetched\n",
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <ac/errno.h>
|
||||||
#include <ac/socket.h>
|
#include <ac/socket.h>
|
||||||
#include <ac/string.h>
|
#include <ac/string.h>
|
||||||
#include <ac/errno.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
#include "slap.h"
|
||||||
#include "../back-ldap/back-ldap.h"
|
#include "../back-ldap/back-ldap.h"
|
||||||
@ -47,7 +47,16 @@ meta_back_conn_destroy(
|
|||||||
|
|
||||||
mc_curr.mc_conn = conn;
|
mc_curr.mc_conn = conn;
|
||||||
|
|
||||||
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
|
retry_lock:;
|
||||||
|
switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
|
||||||
|
case LDAP_PVT_THREAD_EBUSY:
|
||||||
|
default:
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
|
goto retry_lock;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
|
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
|
||||||
meta_back_conn_cmp );
|
meta_back_conn_cmp );
|
||||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
|
||||||
|
Loading…
Reference in New Issue
Block a user