mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 00:29:35 -05:00
keep count of requests in use
This commit is contained in:
parent
517ae66152
commit
b45c0c881d
3 changed files with 92 additions and 27 deletions
|
|
@ -263,23 +263,24 @@ typedef struct ldap_conn {
|
|||
* structure used to track outstanding requests
|
||||
*/
|
||||
typedef struct ldapreq {
|
||||
ber_int_t lr_msgid; /* the message id */
|
||||
ber_int_t lr_msgid; /* the message id */
|
||||
int lr_status; /* status of request */
|
||||
#define LDAP_REQST_COMPLETED 0
|
||||
#define LDAP_REQST_INPROGRESS 1
|
||||
#define LDAP_REQST_CHASINGREFS 2
|
||||
#define LDAP_REQST_NOTCONNECTED 3
|
||||
#define LDAP_REQST_WRITING 4
|
||||
int lr_refcnt; /* count of references */
|
||||
int lr_outrefcnt; /* count of outstanding referrals */
|
||||
ber_int_t lr_origid; /* original request's message id */
|
||||
ber_int_t lr_origid; /* original request's message id */
|
||||
int lr_parentcnt; /* count of parent requests */
|
||||
ber_tag_t lr_res_msgtype; /* result message type */
|
||||
ber_int_t lr_res_errno; /* result LDAP errno */
|
||||
ber_tag_t lr_res_msgtype; /* result message type */
|
||||
ber_int_t lr_res_errno; /* result LDAP errno */
|
||||
char *lr_res_error; /* result error string */
|
||||
char *lr_res_matched;/* result matched DN string */
|
||||
BerElement *lr_ber; /* ber encoded request contents */
|
||||
LDAPConn *lr_conn; /* connection used to send request */
|
||||
struct berval lr_dn; /* DN of request, in lr_ber */
|
||||
struct berval lr_dn; /* DN of request, in lr_ber */
|
||||
struct ldapreq *lr_parent; /* request that spawned this referral */
|
||||
struct ldapreq *lr_child; /* first child request */
|
||||
struct ldapreq *lr_refnext; /* next referral spawned */
|
||||
|
|
@ -532,6 +533,7 @@ LDAP_F (void) ldap_set_ber_options( LDAP *ld, BerElement *ber );
|
|||
LDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc **srvlist, LDAPConn *lc, LDAPreqinfo *bind );
|
||||
LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
|
||||
LDAP_F (LDAPRequest *) ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid );
|
||||
LDAP_F (void) ldap_return_request_by_msgid( LDAP *ld, LDAPRequest *lr, int freeit );
|
||||
LDAP_F (void) ldap_free_request( LDAP *ld, LDAPRequest *lr );
|
||||
LDAP_F (void) ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
|
||||
LDAP_F (void) ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
|
||||
|
|
|
|||
|
|
@ -293,7 +293,8 @@ ldap_send_server_request(
|
|||
}
|
||||
|
||||
lr->lr_prev = NULL;
|
||||
if (( lr->lr_next = ld->ld_requests ) != NULL ) {
|
||||
lr->lr_next = ld->ld_requests;
|
||||
if ( lr->lr_next != NULL ) {
|
||||
lr->lr_next->lr_prev = lr;
|
||||
}
|
||||
ld->ld_requests = lr;
|
||||
|
|
@ -740,10 +741,20 @@ ldap_dump_requests_and_responses( LDAP *ld )
|
|||
static void
|
||||
ldap_free_request_int( LDAP *ld, LDAPRequest *lr )
|
||||
{
|
||||
/* if lr_refcnt > 0, the request has been looked up
|
||||
* by ldap_find_request_by_msgid(); if in the meanwhile
|
||||
* the request is free()'d by someone else, just decrease
|
||||
* the reference count and extract it from the request
|
||||
* list; later on, it will be freed. */
|
||||
if ( lr->lr_prev == NULL ) {
|
||||
/* free'ing the first request? */
|
||||
assert( ld->ld_requests == lr );
|
||||
ld->ld_requests = lr->lr_next;
|
||||
if ( lr->lr_refcnt == 0 ) {
|
||||
/* free'ing the first request? */
|
||||
assert( ld->ld_requests == lr );
|
||||
}
|
||||
|
||||
if ( ld->ld_requests == lr ) {
|
||||
ld->ld_requests = lr->lr_next;
|
||||
}
|
||||
|
||||
} else {
|
||||
lr->lr_prev->lr_next = lr->lr_next;
|
||||
|
|
@ -753,6 +764,15 @@ ldap_free_request_int( LDAP *ld, LDAPRequest *lr )
|
|||
lr->lr_next->lr_prev = lr->lr_prev;
|
||||
}
|
||||
|
||||
if ( lr->lr_refcnt > 0 ) {
|
||||
lr->lr_refcnt = -lr->lr_refcnt;
|
||||
|
||||
lr->lr_prev = NULL;
|
||||
lr->lr_next = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( lr->lr_ber != NULL ) {
|
||||
ber_free( lr->lr_ber, 1 );
|
||||
lr->lr_ber = NULL;
|
||||
|
|
@ -788,8 +808,10 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr )
|
|||
|
||||
if ( lr->lr_parent != NULL ) {
|
||||
--lr->lr_parent->lr_outrefcnt;
|
||||
for ( ttmplr = &lr->lr_parent->lr_child; *ttmplr && *ttmplr != lr; ttmplr = &(*ttmplr)->lr_refnext );
|
||||
if ( *ttmplr == lr )
|
||||
for ( ttmplr = &lr->lr_parent->lr_child;
|
||||
*ttmplr && *ttmplr != lr;
|
||||
ttmplr = &(*ttmplr)->lr_refnext );
|
||||
if ( *ttmplr == lr )
|
||||
*ttmplr = lr->lr_refnext;
|
||||
}
|
||||
ldap_free_request_int( ld, lr );
|
||||
|
|
@ -1422,6 +1444,7 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
|
|||
continue; /* Skip completed requests */
|
||||
}
|
||||
if ( msgid == lr->lr_msgid ) {
|
||||
lr->lr_refcnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1432,4 +1455,35 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
|
|||
return( lr );
|
||||
}
|
||||
|
||||
void
|
||||
ldap_return_request_by_msgid( LDAP *ld, LDAPRequest *lrx, int freeit )
|
||||
{
|
||||
LDAPRequest *lr;
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
if ( lr == lrx ) {
|
||||
if ( lr->lr_refcnt > 0 ) {
|
||||
lr->lr_refcnt--;
|
||||
|
||||
} else if ( lr->lr_refcnt < 0 ) {
|
||||
lr->lr_refcnt++;
|
||||
if ( lr->lr_refcnt == 0 ) {
|
||||
lr = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( lr == NULL ) {
|
||||
ldap_free_request_int( ld, lrx );
|
||||
|
||||
} else if ( freeit ) {
|
||||
ldap_free_request( ld, lrx );
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,6 +337,7 @@ wait4msg(
|
|||
|
||||
if ( rc == -1 ) {
|
||||
rc = LDAP_MSG_X_KEEP_LOOKING; /* select interrupted: loop */
|
||||
|
||||
} else {
|
||||
rc = LDAP_MSG_X_KEEP_LOOKING;
|
||||
#ifdef LDAP_R_COMPILE
|
||||
|
|
@ -577,6 +578,7 @@ nextresp2:
|
|||
/* Get the referral list */
|
||||
if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) {
|
||||
rc = LDAP_DECODING_ERROR;
|
||||
|
||||
} else {
|
||||
/* Note: refs array is freed by ldap_chase_v3referrals */
|
||||
refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
|
||||
|
|
@ -598,6 +600,7 @@ nextresp2:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Check for V3 referral */
|
||||
ber_len_t len;
|
||||
|
|
@ -608,14 +611,12 @@ nextresp2:
|
|||
!= LBER_ERROR )
|
||||
{
|
||||
if ( lr_res_error != NULL ) {
|
||||
{
|
||||
if ( lr->lr_res_error != NULL ) {
|
||||
(void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
|
||||
LDAP_FREE( (char *)lr_res_error );
|
||||
if ( lr->lr_res_error != NULL ) {
|
||||
(void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
|
||||
LDAP_FREE( (char *)lr_res_error );
|
||||
|
||||
} else {
|
||||
lr->lr_res_error = lr_res_error;
|
||||
}
|
||||
} else {
|
||||
lr->lr_res_error = lr_res_error;
|
||||
}
|
||||
lr_res_error = NULL;
|
||||
}
|
||||
|
|
@ -637,6 +638,7 @@ nextresp2:
|
|||
Debug( LDAP_DEBUG_TRACE,
|
||||
"read1msg: referral decode error, mark request completed, ld %p msgid %d\n",
|
||||
(void *)ld, lr->lr_msgid, 0);
|
||||
|
||||
} else {
|
||||
/* Chase the referral
|
||||
* Note: refs arrary is freed by ldap_chase_v3referrals
|
||||
|
|
@ -659,6 +661,7 @@ nextresp2:
|
|||
LDAP_FREE( lr->lr_res_matched );
|
||||
lr->lr_res_matched = NULL;
|
||||
}
|
||||
|
||||
if( lr->lr_res_error != NULL ) {
|
||||
LDAP_FREE( lr->lr_res_error );
|
||||
lr->lr_res_error = NULL;
|
||||
|
|
@ -690,6 +693,7 @@ nextresp2:
|
|||
*/
|
||||
if ( tag == LDAP_RES_SEARCH_RESULT )
|
||||
refer_cnt = 0;
|
||||
|
||||
} else if ( ber_scanf( &tmpber, "{eAA}", &lderr,
|
||||
&lr->lr_res_matched, &lr_res_error )
|
||||
!= LBER_ERROR )
|
||||
|
|
@ -733,8 +737,10 @@ nextresp2:
|
|||
lr->lr_res_errno = ( lderr ==
|
||||
LDAP_PARTIAL_RESULTS ) ? LDAP_SUCCESS
|
||||
: lderr;
|
||||
|
||||
} else if ( ld->ld_errno != LDAP_SUCCESS ) {
|
||||
lr->lr_res_errno = ld->ld_errno;
|
||||
|
||||
} else {
|
||||
lr->lr_res_errno = LDAP_PARTIAL_RESULTS;
|
||||
}
|
||||
|
|
@ -762,13 +768,16 @@ nextresp2:
|
|||
ber_free( ber, 1 );
|
||||
ber = NULL;
|
||||
if ( refer_cnt < 0 ) {
|
||||
ldap_return_request_by_msgid( ld, lr, 0 );
|
||||
return( -1 ); /* fatal error */
|
||||
}
|
||||
lr->lr_res_errno = LDAP_SUCCESS; /* sucessfully chased referral */
|
||||
|
||||
} else {
|
||||
if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL ) {
|
||||
/* request without any referrals */
|
||||
simple_request = ( hadref ? 0 : 1 );
|
||||
|
||||
} else {
|
||||
/* request with referrals or child request */
|
||||
ber_free( ber, 1 );
|
||||
|
|
@ -791,9 +800,9 @@ nextresp2:
|
|||
/* Check if all requests are finished, lr is now parent */
|
||||
tmplr = lr;
|
||||
if ( tmplr->lr_status == LDAP_REQST_COMPLETED ) {
|
||||
for ( tmplr=lr->lr_child;
|
||||
for ( tmplr = lr->lr_child;
|
||||
tmplr != NULL;
|
||||
tmplr=tmplr->lr_refnext)
|
||||
tmplr = tmplr->lr_refnext )
|
||||
{
|
||||
if ( tmplr->lr_status != LDAP_REQST_COMPLETED ) break;
|
||||
}
|
||||
|
|
@ -821,13 +830,8 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
ldap_free_request( ld, lr );
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
ldap_return_request_by_msgid( ld, lr, 1 );
|
||||
lr = NULL;
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
|
|
@ -843,6 +847,11 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
|||
}
|
||||
}
|
||||
|
||||
if ( lr != NULL ) {
|
||||
ldap_return_request_by_msgid( ld, lr, 0 );
|
||||
lr = NULL;
|
||||
}
|
||||
|
||||
if ( ber == NULL ) {
|
||||
return( rc );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue