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,