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,