Commit 48f2ad98 authored by Doug MacEachern's avatar Doug MacEachern
Browse files

output filter optimizations:

- avoid creating a new bucket brigade for each EOS or FLUSH bucket
- do not pass FLUSH bucket since BIO_bucket_flush() already does so
  if there is any data to flush.
- do not call apr_brigade_destroy(bb); since we will have either
  emptied it or passed it, in which case it will be destroyed further
  down the chain.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/ssl@92885 13f79535-47bb-0310-9956-ffa450edef68
parent 1ae6d23b
Loading
Loading
Loading
Loading
+26 −24
Changes for ssl_engine_io.c: 26 added lines, 24 removed lines.
Original line number Diff line number Diff line
@@ -562,54 +562,56 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
static apr_status_t ssl_io_filter_Output(ap_filter_t *f,
                                         apr_bucket_brigade *bb)
{
    SSLFilterRec *ctx = f->ctx;
    apr_bucket *bucket;
    apr_status_t ret = APR_SUCCESS;
    apr_status_t status = APR_SUCCESS;

    while (!APR_BRIGADE_EMPTY(bb)) {
        const char *data;
        apr_size_t len;

        bucket = APR_BRIGADE_FIRST(bb);
        apr_bucket *bucket = APR_BRIGADE_FIRST(bb);

        /* If it is a flush or EOS, we need to pass this down. 
         * These types do not require translation by OpenSSL.  
         */
        if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) {
            apr_bucket_brigade *outbb;
            int done = APR_BUCKET_IS_EOS(bucket);
            SSLFilterRec *ctx = f->ctx;

            if ((ret = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
                return ret;
            if ((status = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
                return status;
            }

            outbb = apr_brigade_create(f->c->pool);
            APR_BUCKET_REMOVE(bucket);
            APR_BRIGADE_INSERT_TAIL(outbb, bucket);
            ret = ap_pass_brigade(f->next, outbb);
            if (ret != APR_SUCCESS) {
                return ret;
            }
            if (APR_BUCKET_IS_EOS(bucket)) {
                /* By definition, nothing can come after EOS.
                 * which also means we can pass the rest of this brigade
                 * without creating a new one since it only contains the
                 * EOS bucket.
                 */

            /* By definition, nothing can come after EOS. */
            if (done) {
                if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
                    return status;
                }
                break;
            }
            else {
                /* BIO_bucket_flush() already passed down a flush bucket
                 * if there was any data to be flushed.
                 */
                apr_bucket_delete(bucket);
            }
        }
        else {
            /* read filter */
            const char *data;
            apr_size_t len;

            apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
            ret = ssl_filter_write(f, data, len);
            status = ssl_filter_write(f, data, len);
            apr_bucket_delete(bucket);

            if (ret != APR_SUCCESS) {
            if (status != APR_SUCCESS) {
                break;
            }
        }
    }

    apr_brigade_destroy(bb);
    return ret;
    return status;
}

/*