Commit e496db1c authored by Doug MacEachern's avatar Doug MacEachern
Browse files

rather than creating small 1024 byte buckets of output data,

create a transient bucket pointing directly to the BIO mem buff.
this makes for a dramatic increase in performance. previously,
downloading large files (2Mb-5Mb-ish) made my laptop start to
smoke from the fan spinning so fast to cool the cpu.
also, apache stylize churn_output()
PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90497 13f79535-47bb-0310-9956-ffa450edef68
parent a6e04c16
Loading
Loading
Loading
Loading
+27 −36
Original line number Diff line number Diff line
@@ -144,56 +144,47 @@ static int ssl_io_hook_write(SSL *ssl, unsigned char *buf, int len)
    return rc;
}

static apr_status_t churn_output(SSLFilterRec *pRec)
{
    conn_rec *c = pRec->pOutputFilter->c;
    apr_pool_t *p = c->pool;
#define BIO_mem(b) ((BUF_MEM *)b->ptr)

    apr_bucket_brigade *pbbOutput=NULL;
    int done;
static apr_status_t churn_output(SSLFilterRec *ctx)
{
    ap_filter_t *f = ctx->pOutputFilter;
    apr_pool_t *p = f->c->pool;
    apr_bucket_brigade *bb = NULL;

    if (!pRec->pssl) {
    if (!ctx->pssl) {
        /* we've been shutdown */
        return APR_EOF;
    }

    do {
	char buf[1024];
	int n;
	apr_bucket *pbkt;
    if (BIO_pending(ctx->pbioWrite)) {
        BUF_MEM *bm = BIO_mem(ctx->pbioWrite);
        apr_bucket *bucket; 

	done=0;
        bb = apr_brigade_create(p);

	if (BIO_pending(pRec->pbioWrite)) {
            n = BIO_read(pRec->pbioWrite, buf, sizeof buf);
            if(n > 0) {
		char *pbuf;
        /*
         * use the BIO memory buffer that has already been allocated,
         * rather than making another copy of it.
         * use bm directly here is *much* faster than calling BIO_read()
         * look at crypto/bio/bss_mem.c:mem_read and you'll see why
         */

		if(!pbbOutput)
		    pbbOutput = apr_brigade_create(p);
        bucket = apr_bucket_transient_create((const char *)bm->data,
                                             bm->length);

		pbuf = apr_pmemdup(p, buf, n);
		pbkt = apr_bucket_pool_create(pbuf, n, p);
		APR_BRIGADE_INSERT_TAIL(pbbOutput,pbkt);
		done=1;
	    }
            else {
                ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
                        "attempting to read %d bytes from wbio, got %d",
                        sizeof buf, n);
                return APR_EINVAL;
            }
        bm->length = 0; /* reset */

        APR_BRIGADE_INSERT_TAIL(bb, bucket);
    }
    } while(done);
    
    /* XXX: check for errors */
    if(pbbOutput) {
	apr_bucket *pbkt;
    if (bb) {
	apr_bucket *bucket = apr_bucket_flush_create();

	/* XXX: it may be possible to not always flush */
	pbkt=apr_bucket_flush_create();
	APR_BRIGADE_INSERT_TAIL(pbbOutput,pbkt);
	ap_pass_brigade(pRec->pOutputFilter->next,pbbOutput);
	APR_BRIGADE_INSERT_TAIL(bb, bucket);
	ap_pass_brigade(f->next, bb);
    }

    return APR_SUCCESS;