]> granicus.if.org Git - apache/commitdiff
Merge r1234899:
authorStefan Fritsch <sf@apache.org>
Tue, 31 Jan 2012 21:45:29 +0000 (21:45 +0000)
committerStefan Fritsch <sf@apache.org>
Tue, 31 Jan 2012 21:45:29 +0000 (21:45 +0000)
    * server/core_filters.c (send_brigade_nonblocking): Use a non-blocking
      bucket read, allowing any pending data to be flushed before trying a
      (potentially slow) blocking read.

Submitted by: Joe Orton

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1238822 13f79535-47bb-0310-9956-ffa450edef68

server/core_filters.c

index bd1b41e0625612db2c10625f3960559c64fcdde2..61c4a4115fcc5b7d22ac92ab958314702bf527a6 100644 (file)
@@ -654,10 +654,26 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
         if (!APR_BUCKET_IS_METADATA(bucket)) {
             const char *data;
             apr_size_t length;
-            rv = apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
+            
+            /* Non-blocking read first, in case this is a morphing
+             * bucket type. */
+            rv = apr_bucket_read(bucket, &data, &length, APR_NONBLOCK_READ);
+            if (APR_STATUS_IS_EAGAIN(rv)) {
+                /* Read would block; flush any pending data and retry. */
+                if (nvec) {
+                    rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
+                    if (rv) {
+                        return rv;
+                    }
+                    nvec = 0;
+                }
+                
+                rv = apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
+            }
             if (rv != APR_SUCCESS) {
                 return rv;
             }
+
             /* reading may have split the bucket, so recompute next: */
             next = APR_BUCKET_NEXT(bucket);
             vec[nvec].iov_base = (char *)data;