]> git.sur5r.net Git - openldap/commitdiff
Fix ITS#1983, handle writing of large requests. Only one pending request is
authorHoward Chu <hyc@openldap.org>
Thu, 29 Aug 2002 12:12:36 +0000 (12:12 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 29 Aug 2002 12:12:36 +0000 (12:12 +0000)
allowed per LDAP* handle. It works, but needs review.

libraries/libldap/abandon.c
libraries/libldap/ldap-int.h
libraries/libldap/request.c
libraries/libldap/result.c

index a88a5865b5a89ab8813b2c49ababf82bd4954ee3..04397a275edb9f28d8e04a68c288ca75adfc5024 100644 (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 ) {
index 4ad20dd9f4c813a6172fbc9e940e42b441803d9d..5e44c3287dd399130b723ddcab8b0cd1edd0995a 100644 (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:
index b9ecd9b3bd3a8ca7b50962b4fabfc288b1518e95..c45a7769f5935027a35b1e18b39cfc40b6dc9392 100644 (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;
index 1a7bcec9efff41fa9bd692f91cab037538a24cea..2f82aa94227ed6a061b3ace32330464be765d5bb 100644 (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;