version 1.124.2.16, 2009/01/26 20:57:37
|
version 1.124.2.17, 2009/02/10 23:42:16
|
Line 1
|
Line 1
|
/* result.c - wait for an ldap result */ |
/* result.c - wait for an ldap result */ |
/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.124.2.15 2009/01/22 00:00:55 kurt Exp $ */ |
/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.124.2.16 2009/01/26 20:57:37 quanah Exp $ */ |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
* |
* |
* Copyright 1998-2009 The OpenLDAP Foundation. |
* Copyright 1998-2009 The OpenLDAP Foundation. |
Line 71 static int ldap_mark_abandoned LDAP_P((
|
Line 71 static int ldap_mark_abandoned LDAP_P((
|
static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, |
static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, |
LDAPMessage **result )); |
LDAPMessage **result )); |
static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid, |
static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid, |
int all, LDAPConn **lc, LDAPMessage **result )); |
int all, LDAPConn *lc, LDAPMessage **result )); |
static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr )); |
static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr )); |
static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )); |
static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )); |
static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all)); |
static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all)); |
Line 106 ldap_result(
|
Line 106 ldap_result(
|
struct timeval *timeout, |
struct timeval *timeout, |
LDAPMessage **result ) |
LDAPMessage **result ) |
{ |
{ |
LDAPMessage *lm = NULL; |
LDAPMessage *lm; |
int rc; |
int rc; |
|
|
assert( ld != NULL ); |
assert( ld != NULL ); |
Line 118 ldap_result(
|
Line 118 ldap_result(
|
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex ); |
#endif |
#endif |
|
|
#if 0 |
rc = wait4msg( ld, msgid, all, timeout, result ); |
/* this is already done inside wait4msg(), right?... */ |
|
lm = chkResponseList( ld, msgid, all ); |
|
#endif |
|
|
|
if ( lm == NULL ) { |
|
rc = wait4msg( ld, msgid, all, timeout, result ); |
|
|
|
} else { |
|
*result = lm; |
|
ld->ld_errno = LDAP_SUCCESS; |
|
rc = lm->lm_msgtype; |
|
} |
|
|
|
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex ); |
ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex ); |
Line 335 wait4msg(
|
Line 323 wait4msg(
|
if ( ber_sockbuf_ctrl( lc->lconn_sb, |
if ( ber_sockbuf_ctrl( lc->lconn_sb, |
LBER_SB_OPT_DATA_READY, NULL ) ) |
LBER_SB_OPT_DATA_READY, NULL ) ) |
{ |
{ |
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); |
|
#endif |
|
rc = try_read1msg( ld, msgid, all, &lc, result ); |
|
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); |
|
#endif |
|
lc_ready = 1; |
lc_ready = 1; |
break; |
break; |
} |
} |
Line 375 wait4msg(
|
Line 356 wait4msg(
|
rc = LDAP_MSG_X_KEEP_LOOKING; /* select interrupted: loop */ |
rc = LDAP_MSG_X_KEEP_LOOKING; /* select interrupted: loop */ |
|
|
} else { |
} else { |
rc = LDAP_MSG_X_KEEP_LOOKING; |
lc_ready = 1; |
|
} |
|
} |
|
if ( lc_ready ) { |
|
LDAPConn *lnext; |
|
rc = LDAP_MSG_X_KEEP_LOOKING; |
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
#endif |
#endif |
if ( ld->ld_requests && |
if ( ld->ld_requests && |
ld->ld_requests->lr_status == LDAP_REQST_WRITING && |
ld->ld_requests->lr_status == LDAP_REQST_WRITING && |
ldap_is_write_ready( ld, |
ldap_is_write_ready( ld, |
ld->ld_requests->lr_conn->lconn_sb ) ) |
ld->ld_requests->lr_conn->lconn_sb ) ) |
{ |
{ |
ldap_int_flush_request( ld, ld->ld_requests ); |
ldap_int_flush_request( ld, ld->ld_requests ); |
} |
} |
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); |
#endif |
#endif |
for ( lc = ld->ld_conns; |
for ( lc = ld->ld_conns; |
rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL; ) |
rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL; |
|
lc = lnext ) |
|
{ |
|
if ( lc->lconn_status == LDAP_CONNST_CONNECTED && |
|
ldap_is_read_ready( ld, lc->lconn_sb ) ) |
{ |
{ |
if ( lc->lconn_status == LDAP_CONNST_CONNECTED && |
/* Don't let it get freed out from under us */ |
ldap_is_read_ready( ld, lc->lconn_sb ) ) |
++lc->lconn_refcnt; |
{ |
|
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); |
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); |
#endif |
#endif |
rc = try_read1msg( ld, msgid, all, &lc, result ); |
rc = try_read1msg( ld, msgid, all, lc, result ); |
|
lnext = lc->lconn_next; |
|
|
|
/* Only take locks if we're really freeing */ |
|
if ( lc->lconn_refcnt <= 1 ) { |
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
#endif |
#endif |
if ( lc == NULL ) { |
ldap_free_connection( ld, lc, 0, 1 ); |
/* if lc gets free()'d, |
#ifdef LDAP_R_COMPILE |
* there's no guarantee |
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
* lc->lconn_next is still |
#endif |
* sane; better restart |
} else { |
* (ITS#4405) */ |
--lc->lconn_refcnt; |
lc = ld->ld_conns; |
|
|
|
/* don't get to next conn! */ |
|
break; |
|
} |
|
} |
} |
|
|
/* next conn */ |
|
lc = lc->lconn_next; |
|
} |
|
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); |
ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); |
#endif |
#endif |
|
} else { |
|
lnext = lc->lconn_next; |
|
} |
} |
} |
|
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); |
|
#endif |
} |
} |
} |
} |
|
|
Line 482 try_read1msg(
|
Line 472 try_read1msg(
|
LDAP *ld, |
LDAP *ld, |
ber_int_t msgid, |
ber_int_t msgid, |
int all, |
int all, |
LDAPConn **lcp, |
LDAPConn *lc, |
LDAPMessage **result ) |
LDAPMessage **result ) |
{ |
{ |
BerElement *ber; |
BerElement *ber; |
Line 493 try_read1msg(
|
Line 483 try_read1msg(
|
ber_len_t len; |
ber_len_t len; |
int foundit = 0; |
int foundit = 0; |
LDAPRequest *lr, *tmplr, dummy_lr = { 0 }; |
LDAPRequest *lr, *tmplr, dummy_lr = { 0 }; |
LDAPConn *lc; |
|
BerElement tmpber; |
BerElement tmpber; |
int rc, refer_cnt, hadref, simple_request, err; |
int rc, refer_cnt, hadref, simple_request, err; |
ber_int_t lderr; |
ber_int_t lderr; |
Line 504 try_read1msg(
|
Line 493 try_read1msg(
|
#endif |
#endif |
|
|
assert( ld != NULL ); |
assert( ld != NULL ); |
assert( lcp != NULL ); |
assert( lc != NULL ); |
assert( *lcp != NULL ); |
|
|
|
#ifdef LDAP_R_COMPILE |
#ifdef LDAP_R_COMPILE |
LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex ); |
LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex ); |
Line 514 try_read1msg(
|
Line 502 try_read1msg(
|
Debug( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d all %d\n", |
Debug( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d all %d\n", |
(void *)ld, msgid, all ); |
(void *)ld, msgid, all ); |
|
|
lc = *lcp; |
|
|
|
retry: |
retry: |
if ( lc->lconn_ber == NULL ) { |
if ( lc->lconn_ber == NULL ) { |
lc->lconn_ber = ldap_alloc_ber_with_options( ld ); |
lc->lconn_ber = ldap_alloc_ber_with_options( ld ); |
Line 561 nextresp3:
|
Line 547 nextresp3:
|
if ( err == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING; |
if ( err == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING; |
#endif |
#endif |
ld->ld_errno = LDAP_SERVER_DOWN; |
ld->ld_errno = LDAP_SERVER_DOWN; |
#ifdef LDAP_R_COMPILE |
--lc->lconn_refcnt; |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
lc->lconn_status = 0; |
#endif |
|
ldap_free_connection( ld, lc, 1, 0 ); |
|
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
|
#endif |
|
lc = *lcp = NULL; |
|
return -1; |
return -1; |
|
|
default: |
default: |
Line 938 nextresp2:
|
Line 918 nextresp2:
|
* shouldn't necessarily end the connection |
* shouldn't necessarily end the connection |
*/ |
*/ |
if ( lc != NULL && id != 0 ) { |
if ( lc != NULL && id != 0 ) { |
#ifdef LDAP_R_COMPILE |
--lc->lconn_refcnt; |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
lc = NULL; |
#endif |
|
ldap_free_connection( ld, lc, 0, 1 ); |
|
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
|
#endif |
|
lc = *lcp = NULL; |
|
} |
} |
} |
} |
} |
} |
Line 1011 nextresp2:
|
Line 985 nextresp2:
|
|
|
/* get rid of the connection... */ |
/* get rid of the connection... */ |
if ( lc != NULL ) { |
if ( lc != NULL ) { |
#ifdef LDAP_R_COMPILE |
--lc->lconn_refcnt; |
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); |
|
#endif |
|
ldap_free_connection( ld, lc, 0, 1 ); |
|
#ifdef LDAP_R_COMPILE |
|
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); |
|
#endif |
|
lc = *lcp = NULL; |
|
} |
} |
|
|
/* need to return -1, because otherwise |
/* need to return -1, because otherwise |