serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1709651 - in /serf/trunk: outgoing.c serf_private.h
Date Tue, 20 Oct 2015 17:19:52 GMT
Author: rhuijben
Date: Tue Oct 20 17:19:52 2015
New Revision: 1709651

URL: http://svn.apache.org/viewvc?rev=1709651&view=rev
Log:
Following up on r1709631 and r1709641, move the pump to the network logic
from the http1-style connection writer to the serf__connection_flush()
helper function.

The previous two patches in this set fixed issues that made it
impossible to extract the code.

* serf-dev/dev/outgoing.c
  (serf__connection_flush): Add pump argument. Move pump logic here. Make the
    SERF_ERROR_WAIT_CONN logic return APR_EAGAIN, which our callers handle by
    returning success, like the old stop_reading did.
  (write_to_connection): Extract code here. Update caller.

* serf-dev/dev/serf_private.h
  (serf__connection_flush): Update prototype.

Modified:
    serf/trunk/outgoing.c
    serf/trunk/serf_private.h

Modified: serf/trunk/outgoing.c
URL: http://svn.apache.org/viewvc/serf/trunk/outgoing.c?rev=1709651&r1=1709650&r2=1709651&view=diff
==============================================================================
--- serf/trunk/outgoing.c (original)
+++ serf/trunk/outgoing.c Tue Oct 20 17:19:52 2015
@@ -692,9 +692,60 @@ static apr_status_t socket_writev(serf_c
     return status;
 }
 
-apr_status_t serf__connection_flush(serf_connection_t *conn)
+apr_status_t serf__connection_flush(serf_connection_t *conn,
+                                    int pump)
 {
     apr_status_t status = APR_SUCCESS;
+    apr_status_t read_status = APR_SUCCESS;
+
+    if (pump) {
+        serf_bucket_t *ostreamt, *ostreamh;
+
+        status = prepare_conn_streams(conn, &ostreamt, &ostreamh);
+        if (status) {
+            return status;
+        }
+
+        /* ### optimize at some point by using read_for_sendfile */
+        /* TODO: now that read_iovec will effectively try to return as much
+           data as available, we probably don't want to read ALL_AVAIL, but
+           a lower number, like the size of one or a few TCP packets, the
+           available TCP buffer size ... */
+        conn->hit_eof = 0;
+        read_status = serf_bucket_read_iovec(ostreamh,
+                                             SERF_READ_ALL_AVAIL,
+                                             IOV_MAX,
+                                             conn->vec,
+                                             &conn->vec_len);
+
+        if (read_status == SERF_ERROR_WAIT_CONN) {
+            /* The bucket told us that it can't provide more data until
+            more data is read from the socket. This normally happens
+            during a SSL handshake.
+
+            We should avoid looking for writability for a while so
+            that (hopefully) something will appear in the bucket so
+            we can actually write something. otherwise, we could
+            end up in a CPU spin: socket wants something, but we
+            don't have anything (and keep returning EAGAIN) */
+            conn->stop_writing = 1;
+            conn->dirty_conn = 1;
+            conn->ctx->dirty_pollset = 1;
+
+            read_status = APR_EAGAIN;
+        }
+        else if (APR_STATUS_IS_EAGAIN(read_status)) {
+
+            /* We read some stuff, but did we read everything ? */
+            if (conn->hit_eof)
+                read_status = APR_SUCCESS;
+        }
+        else if (SERF_BUCKET_READ_ERROR(read_status)) {
+
+            /* Something bad happened. Propagate any errors. */
+            return read_status;
+        }
+    }
 
     while (conn->vec_len && !status) {
         status = socket_writev(conn);
@@ -708,7 +759,8 @@ apr_status_t serf__connection_flush(serf
             return no_more_writes(conn);
 
     }
-    return status;
+
+    return status ? status : read_status;
 }
 
 /* write data out to the connection */
@@ -729,7 +781,6 @@ static apr_status_t write_to_connection(
      */
     while (1) {
         serf_request_t *request;
-        int stop_reading = 0;
         apr_status_t status;
         apr_status_t read_status;
         serf_bucket_t *ostreamt;
@@ -757,7 +808,7 @@ static apr_status_t write_to_connection(
         }
 
         /* If we have unwritten data, then write what we can. */
-        status = serf__connection_flush(conn);
+        status = serf__connection_flush(conn, FALSE);
         if (APR_STATUS_IS_EAGAIN(status))
             return APR_SUCCESS;
         else if (status)
@@ -801,59 +852,15 @@ static apr_status_t write_to_connection(
             }
         }
 
-        /* ### optimize at some point by using read_for_sendfile */
-        /* TODO: now that read_iovec will effectively try to return as much
-           data as available, we probably don't want to read ALL_AVAIL, but
-           a lower number, like the size of one or a few TCP packets, the
-           available TCP buffer size ... */
-        conn->hit_eof = 0;
-        read_status = serf_bucket_read_iovec(ostreamh,
-                                             SERF_READ_ALL_AVAIL,
-                                             IOV_MAX,
-                                             conn->vec,
-                                             &conn->vec_len);
-
-        if (read_status == SERF_ERROR_WAIT_CONN) {
-
-            /* The bucket told us that it can't provide more data until
-               more data is read from the socket. This normally happens
-               during a SSL handshake.
-
-               We should avoid looking for writability for a while so
-               that (hopefully) something will appear in the bucket so
-               we can actually write something. otherwise, we could
-               end up in a CPU spin: socket wants something, but we
-               don't have anything (and keep returning EAGAIN) */
-            conn->stop_writing = 1;
-            conn->dirty_conn = 1;
-            conn->ctx->dirty_pollset = 1;
-        }
-        else if (APR_STATUS_IS_EAGAIN(read_status)) {
-
-            /* We read some stuff, but should not try to read again. */
-
-            if (! conn->hit_eof)
-                stop_reading = 1;
-        }
-        else if (SERF_BUCKET_READ_ERROR(read_status)) {
-
-            /* Something bad happened. Propagate any errors. */
-
-            return read_status;
-        }
-
         /* If we got some data, then deliver it. */
         /* ### what to do if we got no data?? is that a problem? */
-        status = serf__connection_flush(conn);
+        status = serf__connection_flush(conn, TRUE);
         if (APR_STATUS_IS_EAGAIN(status))
             return APR_SUCCESS;
         else if (status)
             return status;
 
-        if (read_status == SERF_ERROR_WAIT_CONN) {
-            stop_reading = 1;
-        }
-        else if (request && conn->hit_eof && conn->vec_len == 0) {
+        if (request && conn->hit_eof && conn->vec_len == 0) {
             /* If we hit the end of the request bucket and all of its data has
              * been written, then clear it out to signify that we're done
              * sending the request. On the next iteration through this loop:
@@ -887,13 +894,9 @@ static apr_status_t write_to_connection(
             if (conn->probable_keepalive_limit &&
                 conn->completed_requests > conn->probable_keepalive_limit) {
                 /* backoff for now. */
-                stop_reading = 1;
+                return APR_SUCCESS;
             }
         }
-
-        if (stop_reading) {
-            return APR_SUCCESS;
-        }
     }
     /* NOTREACHED */
 }

Modified: serf/trunk/serf_private.h
URL: http://svn.apache.org/viewvc/serf/trunk/serf_private.h?rev=1709651&r1=1709650&r2=1709651&view=diff
==============================================================================
--- serf/trunk/serf_private.h (original)
+++ serf/trunk/serf_private.h Tue Oct 20 17:19:52 2015
@@ -511,7 +511,8 @@ serf_request_t *serf__ssltunnel_request_
                                                serf_request_setup_t setup,
                                                void *setup_baton);
 void serf__connection_set_pipelining(serf_connection_t *conn, int enabled);
-apr_status_t serf__connection_flush(serf_connection_t *conn);
+apr_status_t serf__connection_flush(serf_connection_t *conn,
+                                    int pump);
 
 apr_status_t serf__provide_credentials(serf_context_t *ctx,
                                        char **username,



Mime
View raw message