httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Doug MacEachern <do...@covalent.net>
Subject Re: Both ap_r* patches.
Date Sun, 21 Jan 2001 22:48:12 GMT
On Sun, 21 Jan 2001 rbb@covalent.net wrote:
 
> This is pretty consistent with all of the other tests we have run.  I am a
> bit interested in your mod_perl specific patch, because it is slightly
> faster than my patch.  How mod_perl specific is it?

its a super simple buffer api, no patch to core is needed.  not perfect,
but heaps better than ap_rwrite() without either patch:

typedef struct {
    int outcnt;
    char outbuf[IOBUFSIZE];
    apr_pool_t *pool;
    ap_filter_t *filters;
} modperl_wbucket_t;

(note: pool and filters are only used with $filter->write, not $r->write)

MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *wb,
                                            const char *buf, apr_ssize_t
len)
{
    apr_bucket_brigade *bb = apr_brigade_create(wb->pool);
    apr_bucket *bucket = apr_bucket_create_transient(buf, len);
    APR_BRIGADE_INSERT_TAIL(bb, bucket);
    return ap_pass_brigade(wb->filters, bb);
}

MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *wb)
{
    apr_status_t rv = APR_SUCCESS;

    if (wb->outcnt) {
        rv = modperl_wbucket_pass(wb, wb->outbuf, wb->outcnt);
        wb->outcnt = 0;
    }

    return rv;
}

MP_INLINE apr_status_t modperl_wbucket_write(modperl_wbucket_t *wb,
                                             const char *buf,
                                             apr_ssize_t *wlen)
{
    apr_ssize_t len = *wlen;
    *wlen = 0;

    if ((len + wb->outcnt) > sizeof(wb->outbuf)) {
        apr_status_t rv;
        if ((rv = modperl_wbucket_flush(wb)) != APR_SUCCESS) {
            return rv;
        }
    }

    if (len >= sizeof(wb->outbuf)) {
        *wlen = len;
        return modperl_wbucket_pass(wb, buf, len);
    }
    else {
        memcpy(&wb->outbuf[wb->outcnt], buf, len);
        wb->outcnt += len;
        *wlen = len;
        return APR_SUCCESS;
    }
}


the functions are not inlined during my tests (debug flags turned on)

the actual handler looks like this:

    modperl_response_init(r);

    retval = modperl_per_dir_callback(MP_RESPONSE_HANDLER, r);

    modperl_response_finish(r);

where response_init sets up modperl's per-request config
(inside r->per_request_config), which contains a wbucket.
each call to $r->write calls wbucket_write underneath (instead of
ap_rwrite)
after the Perl callbacks are made, response_finish calls wbucket_flush.


Mime
View raw message