Some comments:

@@ -581,6 +564,33 @@
                       eor_buckets_in_brigade, morphing_bucket_in_brigade);
     }
 
+    /* Handle non blocking writes. If we saw a non blocking bucket, attempt
+     * a non blocking write. If the non blocking write would have returned
+     * APR_EGAIN, set aside the remainder and return APR_EAGAIN.
+     */
+    if (nonblock_bucket_in_brigade) {
+        if (loglevel >= APLOG_TRACE6) {
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE8, APR_SUCCESS, c,
+                          "core_output_filter: non blocking write "
+                          "to the network");
+        }
+        rv = send_brigade_nonblocking(net->client_socket, bb,
+                                      &(ctx->bytes_written), c);
+        if (APR_STATUS_IS_EAGAIN(rv)) {
+            setaside_remaining_output(f, ctx, bb, c);
+        }
+        else if (rv != APR_EAGAIN) {

What if rv is APR_SUCCESS?

+            /* The client has aborted the connection */
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
+                          "core_output_filter: writing data to the network");
+            c->aborted = 1;
+        }
+        return rv;
+    }
+
+    /* Otherwise handle a normal write. A non blocking write will be attempted,
+     * but we don't return APR_EAGAIN, we return APR_SUCCESS instead.
+     */
     if (bytes_in_brigade >= THRESHOLD_MIN_WRITE) {
         rv = send_brigade_nonblocking(net->client_socket, bb,
                                       &(ctx->bytes_written), c);



+AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_nonblock = {
+    "EOC", 5, APR_BUCKET_METADATA,
+    apr_bucket_destroy_noop,

I guess this should be something like "NBB" instead of "EOC" (copy and paste 
error?)

Otherwise looks sensible from a brief look.

Regards

Rüdiger

> -----Original Message-----
> From: Graham Leggett 
> Sent: Sonntag, 17. November 2013 20:41
> To: dev@httpd.apache.org
> Subject: [Patch] non blocking writes in core
> 
> Hi all,
> 
> Continuing on from the discussion about how we might support write
> completion in mod_ssl, I have come up with the following patch below.
> 
> I started by changing the event MPM to call all protocol filters instead
> of just the hard coded write filter:
> 
>         rv = ap_pass_brigade(c->output_filters, cs->bb);
> 
> The first thing that this revealed was that we need to pass a non-empty
> brigade down the stack. I needed a metadata bucket to pass down the stack
> to make the brigade not-empty, and so chose to create a metadata bucket
> for this purpose (more on this below).
> 
> The second thing that we needed to support for mod_ssl to have any hope of
> taking advantage of write completion was non-blocking writes to the core
> output filter. This would give mod_ssl the option to setaside any large
> buckets (example: file buckets) and allow the core to enter write
> completion as soon as it saw EAGAIN.
> 
> We can't change the API for ap_pass_brigade() to add a nonblock flag like
> an input filter, but we can pass a NONBLOCK metadata bucket down the
> stack, and this dovetails nicely with our need for a metadata bucket
> above.
> 
> So, this patch does the following:
> 
> - Takes out the "pass NULL to the core output filter" hack that supported
> write completion previously in the event MPM (other MPMs to follow).
> - Add the nonblock bucket, and pass this bucket down the protocol stack
> during write completion.
> - Teach the core output filter how to react to the NONBLOCK bucket,
> returning APR_EAGAIN appropriately when the NONBLOCK bucket is present
> (and APR_SUCCESS when not, as per previous behaviour).
> 
> In theory, this opens the door for us to support asynchronous filters that
> know about NONBLOCK buckets and nonblocking behaviour. In the case of
> naive filters, we may end up with existing blocking behaviour during write
> completion, but this is no worse than we have now.
> 
> Also in theory, all of this can be backported to v2.4.
> 
> Regards,
> Graham
> --

Reply via email to