mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-06-08 16:22:09 -04:00
Added ld_req_mutex and ld_res_mutex to protect ld_requests and ld_responses
queues for multithreaded access to LDAP*'s. Also used to protect writes and reads of ld_sb, respectively. Appears to work...
This commit is contained in:
parent
568829d821
commit
a6b3a92cc5
6 changed files with 158 additions and 45 deletions
|
|
@ -32,7 +32,8 @@ static int do_abandon LDAP_P((
|
|||
ber_int_t origid,
|
||||
ber_int_t msgid,
|
||||
LDAPControl **sctrls,
|
||||
LDAPControl **cctrls));
|
||||
LDAPControl **cctrls,
|
||||
int lock));
|
||||
|
||||
/*
|
||||
* ldap_abandon_ext - perform an ldap extended abandon operation.
|
||||
|
|
@ -67,7 +68,7 @@ ldap_abandon_ext(
|
|||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
return do_abandon( ld, msgid, msgid, sctrls, cctrls );
|
||||
return do_abandon( ld, msgid, msgid, sctrls, cctrls, 1 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -101,7 +102,8 @@ do_abandon(
|
|||
ber_int_t origid,
|
||||
ber_int_t msgid,
|
||||
LDAPControl **sctrls,
|
||||
LDAPControl **cctrls)
|
||||
LDAPControl **cctrls,
|
||||
int lock)
|
||||
{
|
||||
BerElement *ber;
|
||||
int i, err, sendabandon;
|
||||
|
|
@ -118,6 +120,9 @@ do_abandon(
|
|||
|
||||
sendabandon = 1;
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
/* find the request that we are abandoning */
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
if ( lr->lr_msgid == msgid ) { /* this message */
|
||||
|
|
@ -125,9 +130,12 @@ do_abandon(
|
|||
}
|
||||
if ( lr->lr_origid == msgid ) {/* child: abandon it */
|
||||
(void) do_abandon( ld,
|
||||
msgid, lr->lr_msgid, sctrls, cctrls );
|
||||
msgid, lr->lr_msgid, sctrls, cctrls, 0 );
|
||||
}
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
|
||||
if ( lr != NULL ) {
|
||||
if ( origid == msgid && lr->lr_parent != NULL ) {
|
||||
|
|
@ -213,12 +221,18 @@ do_abandon(
|
|||
sb = ld->ld_sb;
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
if ( ber_flush( sb, ber, 1 ) != 0 ) {
|
||||
ld->ld_errno = LDAP_SERVER_DOWN;
|
||||
err = -1;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,6 +302,11 @@ struct ldap {
|
|||
LDAPRequest *ld_requests; /* list of outstanding requests */
|
||||
LDAPMessage *ld_responses; /* list of outstanding responses */
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_t ld_req_mutex;
|
||||
ldap_pvt_thread_mutex_t ld_res_mutex;
|
||||
#endif
|
||||
|
||||
ber_int_t *ld_abandoned; /* array of abandoned requests */
|
||||
|
||||
LDAPCache *ld_cache; /* non-null if cache is initialized */
|
||||
|
|
|
|||
|
|
@ -160,6 +160,10 @@ ldap_create( LDAP **ldp )
|
|||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
|
||||
ldap_pvt_thread_mutex_init( &ld->ld_res_mutex );
|
||||
#endif
|
||||
*ldp = ld;
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
|
@ -419,6 +423,7 @@ int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
|
|||
lr->lr_msgid = 0;
|
||||
lr->lr_status = LDAP_REQST_INPROGRESS;
|
||||
lr->lr_res_errno = LDAP_SUCCESS;
|
||||
/* no mutex lock needed, we just created this ld here */
|
||||
(*ldp)->ld_requests = lr;
|
||||
|
||||
/* Attach the passed socket as the *LDAP's connection */
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ ldap_send_server_request(
|
|||
LDAPreqinfo *bind )
|
||||
{
|
||||
LDAPRequest *lr;
|
||||
int incparent;
|
||||
int incparent, rc;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ENTRY, "ldap_send_server_request\n", 0, 0, 0 );
|
||||
|
|
@ -232,11 +232,19 @@ ldap_send_server_request(
|
|||
* LDAP_BUSY and let the caller retry later. We only allow a single
|
||||
* request to be in WRITING state.
|
||||
*/
|
||||
rc = 0;
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
if ( ld->ld_requests &&
|
||||
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
|
||||
ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
|
||||
return -1;
|
||||
rc = -1;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
if ( rc ) return rc;
|
||||
|
||||
if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
|
||||
NULL ) {
|
||||
|
|
@ -268,17 +276,23 @@ ldap_send_server_request(
|
|||
lr->lr_origid = lr->lr_msgid;
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
if (( lr->lr_next = ld->ld_requests ) != NULL ) {
|
||||
lr->lr_next->lr_prev = lr;
|
||||
}
|
||||
ld->ld_requests = lr;
|
||||
lr->lr_prev = NULL;
|
||||
|
||||
if ( ldap_int_flush_request( ld, lr ) == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
if ( ldap_int_flush_request( ld, lr ) == -1 ) {
|
||||
msgid = -1;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
|
||||
return( msgid );
|
||||
}
|
||||
|
||||
|
|
@ -572,6 +586,9 @@ ldap_dump_requests_and_responses( LDAP *ld )
|
|||
LDAPRequest *lr;
|
||||
LDAPMessage *lm, *l;
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
fprintf( stderr, "** Outstanding Requests:\n" );
|
||||
if (( lr = ld->ld_requests ) == NULL ) {
|
||||
fprintf( stderr, " Empty\n" );
|
||||
|
|
@ -587,7 +604,10 @@ ldap_dump_requests_and_responses( LDAP *ld )
|
|||
fprintf( stderr, " outstanding referrals %d, parent count %d\n",
|
||||
lr->lr_outrefcnt, lr->lr_parentcnt );
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
fprintf( stderr, "** Response Queue:\n" );
|
||||
if (( lm = ld->ld_responses ) == NULL ) {
|
||||
fprintf( stderr, " Empty\n" );
|
||||
|
|
@ -605,6 +625,9 @@ ldap_dump_requests_and_responses( LDAP *ld )
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
}
|
||||
#endif /* LDAP_DEBUG */
|
||||
|
||||
|
|
@ -1241,6 +1264,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
|
|||
{
|
||||
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->lr_status == LDAP_REQST_COMPLETED ) {
|
||||
continue; /* Skip completed requests */
|
||||
|
|
@ -1249,6 +1275,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
|
|||
break;
|
||||
}
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
|
||||
return( lr );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ chkResponseList(
|
|||
msgid, all, 0 );
|
||||
#endif
|
||||
lastlm = NULL;
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
|
||||
nextlm = lm->lm_next;
|
||||
|
||||
|
|
@ -207,6 +210,9 @@ chkResponseList(
|
|||
}
|
||||
lm->lm_next = NULL;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
if( lm == NULL) {
|
||||
|
|
@ -308,7 +314,13 @@ wait4msg(
|
|||
}
|
||||
|
||||
if ( lc == NULL ) {
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
rc = ldap_int_select( ld, tvp );
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
|
|
@ -338,12 +350,18 @@ wait4msg(
|
|||
rc = -2; /* select interrupted: loop */
|
||||
} else {
|
||||
rc = -2;
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
if ( ld->ld_requests &&
|
||||
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
|
||||
ldap_is_write_ready( ld,
|
||||
ld->ld_requests->lr_conn->lconn_sb ) ) {
|
||||
ldap_int_flush_request( ld, ld->ld_requests );
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
|
||||
lc = nextlc ) {
|
||||
nextlc = lc->lconn_next;
|
||||
|
|
@ -417,18 +435,23 @@ try_read1msg(
|
|||
#endif
|
||||
|
||||
retry:
|
||||
if ( lc->lconn_ber == NULL ) {
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
if ( lc->lconn_ber == NULL ) {
|
||||
lc->lconn_ber = ldap_alloc_ber_with_options(ld);
|
||||
|
||||
if( lc->lconn_ber == NULL ) {
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ber = lc->lconn_ber;
|
||||
assert( LBER_VALID (ber) );
|
||||
|
||||
retry2:
|
||||
/* get the next message */
|
||||
errno = 0;
|
||||
#ifdef LDAP_CONNECTIONLESS
|
||||
|
|
@ -437,8 +460,18 @@ retry2:
|
|||
ber_int_sb_read(sb, &from, sizeof(struct sockaddr));
|
||||
}
|
||||
#endif
|
||||
if ( (tag = ber_get_next( sb, &len, ber ))
|
||||
!= LDAP_TAG_MESSAGE ) {
|
||||
tag = ber_get_next( sb, &len, ber );
|
||||
if ( tag == LDAP_TAG_MESSAGE ) {
|
||||
/*
|
||||
* We read a complete message.
|
||||
* The connection should no longer need this ber.
|
||||
*/
|
||||
lc->lconn_ber = NULL;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
if ( tag != LDAP_TAG_MESSAGE ) {
|
||||
if ( tag == LBER_DEFAULT) {
|
||||
#ifdef LDAP_DEBUG
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -462,12 +495,6 @@ retry2:
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We read a complete message.
|
||||
* The connection should no longer need this ber.
|
||||
*/
|
||||
lc->lconn_ber = NULL;
|
||||
|
||||
/* message id */
|
||||
if ( ber_get_int( ber, &id ) == LBER_ERROR ) {
|
||||
ber_free( ber, 1 );
|
||||
|
|
@ -483,12 +510,10 @@ retry2:
|
|||
Debug( LDAP_DEBUG_ANY, "abandoned\n", 0, 0, 0);
|
||||
#endif
|
||||
retry_ber:
|
||||
if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
|
||||
ber_free_buf( ber );
|
||||
ber_init2( ber, NULL, ld->ld_lberoptions );
|
||||
goto retry2;
|
||||
}
|
||||
ber_free( ber, 1 );
|
||||
if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
|
||||
goto retry;
|
||||
}
|
||||
return( -2 ); /* continue looking */
|
||||
}
|
||||
|
||||
|
|
@ -832,6 +857,9 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
|||
* search response.
|
||||
*/
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
prev = NULL;
|
||||
for ( l = ld->ld_responses; l != NULL; l = l->lm_next ) {
|
||||
if ( l->lm_msgid == new->lm_msgid )
|
||||
|
|
@ -843,8 +871,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
|||
if ( l == NULL ) {
|
||||
if ( foundit ) {
|
||||
*result = new;
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
return( tag );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
new->lm_next = ld->ld_responses;
|
||||
|
|
@ -877,11 +904,16 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
|||
else
|
||||
prev->lm_next = l->lm_next;
|
||||
*result = l;
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
return( tag );
|
||||
}
|
||||
|
||||
leave:
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
if ( foundit ) {
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
return( tag );
|
||||
}
|
||||
if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
|
||||
goto retry;
|
||||
}
|
||||
|
|
@ -1056,6 +1088,7 @@ int
|
|||
ldap_msgdelete( LDAP *ld, int msgid )
|
||||
{
|
||||
LDAPMessage *lm, *prev;
|
||||
int rc = 0;
|
||||
|
||||
assert( ld != NULL );
|
||||
|
||||
|
|
@ -1066,24 +1099,30 @@ ldap_msgdelete( LDAP *ld, int msgid )
|
|||
#endif
|
||||
|
||||
prev = NULL;
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) {
|
||||
if ( lm->lm_msgid == msgid )
|
||||
break;
|
||||
prev = lm;
|
||||
}
|
||||
|
||||
if ( lm == NULL )
|
||||
return( -1 );
|
||||
if ( lm == NULL ) {
|
||||
rc = -1;
|
||||
} else {
|
||||
if ( prev == NULL )
|
||||
ld->ld_responses = lm->lm_next;
|
||||
else
|
||||
prev->lm_next = lm->lm_next;
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
if ( lm && ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY )
|
||||
rc = -1;
|
||||
|
||||
if ( prev == NULL )
|
||||
ld->ld_responses = lm->lm_next;
|
||||
else
|
||||
prev->lm_next = lm->lm_next;
|
||||
|
||||
if ( ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,20 +79,31 @@ ldap_ld_free(
|
|||
int err = LDAP_SUCCESS;
|
||||
|
||||
/* free LDAP structure and outstanding requests/responses */
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
while ( ld->ld_requests != NULL ) {
|
||||
ldap_free_request( ld, ld->ld_requests );
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
|
||||
/* free and unbind from all open connections */
|
||||
while ( ld->ld_conns != NULL ) {
|
||||
ldap_free_connection( ld, ld->ld_conns, 1, close );
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
|
||||
next = lm->lm_next;
|
||||
ldap_msgfree( lm );
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
|
||||
#endif
|
||||
|
||||
if ( ld->ld_error != NULL ) {
|
||||
LDAP_FREE( ld->ld_error );
|
||||
|
|
@ -158,6 +169,10 @@ ldap_ld_free(
|
|||
|
||||
ber_sockbuf_free( ld->ld_sb );
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_destroy( &ld->ld_req_mutex );
|
||||
ldap_pvt_thread_mutex_destroy( &ld->ld_res_mutex );
|
||||
#endif
|
||||
LDAP_FREE( (char *) ld );
|
||||
|
||||
return( err );
|
||||
|
|
@ -214,12 +229,18 @@ ldap_send_unbind(
|
|||
return( ld->ld_errno );
|
||||
}
|
||||
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
/* send the message */
|
||||
if ( ber_flush( sb, ber, 1 ) == -1 ) {
|
||||
ld->ld_errno = LDAP_SERVER_DOWN;
|
||||
ber_free( ber, 1 );
|
||||
return( ld->ld_errno );
|
||||
}
|
||||
#ifdef LDAP_R_COMPILE
|
||||
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
|
||||
#endif
|
||||
|
||||
return( LDAP_SUCCESS );
|
||||
return( ld->ld_errno );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue