Fix ITS#1983, handle writing of large requests. Only one pending request is

allowed per LDAP* handle. It works, but needs review.
This commit is contained in:
Howard Chu 2002-08-29 12:12:36 +00:00
parent 20f6bae612
commit 456e6c73ab
4 changed files with 55 additions and 25 deletions

View File

@ -224,7 +224,7 @@ do_abandon(
}
if ( lr != NULL ) {
if ( sendabandon ) {
if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
ldap_free_connection( ld, lr->lr_conn, 0, 1 );
}
if ( origid == msgid ) {

View File

@ -467,6 +467,7 @@ LDAP_F (int) ldap_chase_referrals( LDAP *ld, LDAPRequest *lr,
LDAP_F (int) ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr,
char **refs, int sref, char **referralsp, int *hadrefp );
LDAP_F (int) ldap_append_referral( LDAP *ld, char **referralsp, char *s );
LDAP_F (int) ldap_int_flush_request( LDAP *ld, LDAPRequest *lr );
/*
* in result.c:

View File

@ -137,6 +137,39 @@ ldap_send_initial_request(
}
int
ldap_int_flush_request(
LDAP *ld,
LDAPRequest *lr
)
{
LDAPConn *lc = lr->lr_conn;
if ( ber_flush( lc->lconn_sb, lr->lr_ber, 0 ) != 0 ) {
if ( errno == EWOULDBLOCK || errno == EAGAIN ) {
/* need to continue write later */
lr->lr_status = LDAP_REQST_WRITING;
ldap_mark_select_write( ld, lc->lconn_sb );
ld->ld_errno = LDAP_BUSY;
return -2;
} else {
ld->ld_errno = LDAP_SERVER_DOWN;
ldap_free_request( ld, lr );
ldap_free_connection( ld, lc, 0, 0 );
return( -1 );
}
} else {
if ( lr->lr_parent == NULL ) {
lr->lr_ber->ber_end = lr->lr_ber->ber_ptr;
lr->lr_ber->ber_ptr = lr->lr_ber->ber_buf;
}
lr->lr_status = LDAP_REQST_INPROGRESS;
/* sent -- waiting for a response */
ldap_mark_select_read( ld, lc->lconn_sb );
}
return 0;
}
int
ldap_send_server_request(
@ -189,6 +222,18 @@ ldap_send_server_request(
}
use_connection( ld, lc );
/* If we still have an incomplete write, try to finish it before
* dealing with the new request. If we don't finish here, return
* LDAP_BUSY and let the caller retry later. We only allow a single
* request to be in WRITING state.
*/
if ( ld->ld_requests &&
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
return -1;
}
if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
@ -225,30 +270,8 @@ ldap_send_server_request(
ld->ld_requests = lr;
lr->lr_prev = NULL;
if ( ber_flush( lc->lconn_sb, ber, 0 ) != 0 ) {
#ifdef notyet
if ( errno == EWOULDBLOCK ) {
/* need to continue write later */
lr->lr_status = LDAP_REQST_WRITING;
ldap_mark_select_write( ld, lc->lconn_sb );
} else {
#else /* notyet */
ld->ld_errno = LDAP_SERVER_DOWN;
ldap_free_request( ld, lr );
ldap_free_connection( ld, lc, 0, 0 );
return( -1 );
#endif /* notyet */
#ifdef notyet
}
#endif /* notyet */
} else {
if ( parentreq == NULL ) {
ber->ber_end = ber->ber_ptr;
ber->ber_ptr = ber->ber_buf;
}
/* sent -- waiting for a response */
ldap_mark_select_read( ld, lc->lconn_sb );
if ( ldap_int_flush_request( ld, lr ) == -1 ) {
return -1;
}
ld->ld_errno = LDAP_SUCCESS;

View File

@ -334,6 +334,12 @@ wait4msg(
rc = -2; /* select interrupted: loop */
} else {
rc = -2;
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 );
}
for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
lc = nextlc ) {
nextlc = lc->lconn_next;