Author: rhuijben
Date: Mon Nov  9 16:06:49 2015
New Revision: 1713466

URL: http://svn.apache.org/viewvc?rev=1713466&view=rev
Log:
Make the per connection outgoing data pump a bit safer to use by always
writing out vecs first if there are such vecs.

Only when there are no such vecs it is safe to obtain new vecs from the
aggregate.

* outgoing.c
  (serf__connection_flush): Use while loop to flush vecs first before
    trying to fill the buffer with new data. Continue while successfull.

Modified:
    serf/trunk/outgoing.c

Modified: serf/trunk/outgoing.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/outgoing.c?rev=1713466&r1=1713465&r2=1713466&view=diff
==============================================================================
--- serf/trunk/outgoing.c (original)
+++ serf/trunk/outgoing.c Mon Nov  9 16:06:49 2015
@@ -823,13 +823,39 @@ apr_status_t serf__connection_flush(serf
 {
     apr_status_t status = APR_SUCCESS;
     apr_status_t read_status = APR_SUCCESS;
+    serf_bucket_t *ostreamh = NULL;
 
-    if (pump) {
-        serf_bucket_t *ostreamt, *ostreamh;
+    conn->hit_eof = FALSE;
 
-        status = prepare_conn_streams(conn, &ostreamt, &ostreamh);
-        if (status) {
+    while (status == APR_SUCCESS) {
+
+        /* First try to write out what is already stored in the
+           connection vecs. */
+        while (conn->vec_len && !status) {
+            status = socket_writev(conn);
+
+            /* If the write would have blocked, then we're done.
+             * Don't try to write anything else to the socket.
+             */
+            if (APR_STATUS_IS_EPIPE(status)
+                || APR_STATUS_IS_ECONNRESET(status)
+                || APR_STATUS_IS_ECONNABORTED(status))
+              return no_more_writes(conn);
+        }
+
+        if (status || !pump)
             return status;
+        else if (read_status || conn->vec_len || conn->hit_eof)
+            return read_status;
+
+        /* Ok, with the vecs written, we can now refill the per connection
+           output vecs */
+        if (!ostreamh) {
+            serf_bucket_t *ostreamt;
+
+            status = prepare_conn_streams(conn, &ostreamt, &ostreamh);
+            if (status)
+                return status;
         }
 
         /* ### optimize at some point by using read_for_sendfile */
@@ -873,22 +899,10 @@ apr_status_t serf__connection_flush(serf
         }
     }
 
-    while (conn->vec_len && !status) {
-        status = socket_writev(conn);
-
-        /* If the write would have blocked, then we're done. Don't try
-         * to write anything else to the socket.
-         */
-        if (APR_STATUS_IS_EPIPE(status)
-            || APR_STATUS_IS_ECONNRESET(status)
-            || APR_STATUS_IS_ECONNABORTED(status))
-            return no_more_writes(conn);
-
-    }
-
-    return status ? status : read_status;
+    return status;
 }
 
+
 /* Implements serf_bucket_aggregate_eof_t to mark that the request that is
    already DONE writing has actually FINISHED writing. */
 static apr_status_t request_writing_finished(void *baton,


Reply via email to