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 > --