After damn near forever I've finally gotten around to looking at
mmap_setaside.  It's ugly.  Really ugly.  Here's the best I can come up
with... I'm hoping to get a little feedback.  It won't compile right now
because I use some variables that don't exist yet and functions that
aren't available to me, but it's at least readable so you can get the jist
of what I'm trying to do.

Comments?

Thanks,
--Cliff


static apr_status_t mmap_setaside(apr_bucket *b, apr_pool_t *reqpool)
{
    apr_bucket_mmap *m = b->data;
    apr_mmap_t *mm = m->mmap;
    apr_pool_t *curpool = mm->cntxt;
    apr_status_t rv = APR_SUCCESS;

    /* if the current pool is an ancestor of the requested pool, we're
     * already done. otherwise... */
    if (!apr_pool_is_ancestor(curpool, reqpool)) {
        if (apr_pool_is_ancestor(reqpool, curpool)) {
            /* if requested pool is an ancestor of the current pool, we can
             * just tweak the lifetime of the apr_mmap_t to be equal to the
             * life of reqpool, and everyone should be happy. */
            /* XXX: mmap_cleanup is not available to us because it's static
             * to the apr_mmap code... what to do, what to do?  it's too bad
             * there's not some APR function to do all this for us, but
             * I'm not convinced it would sense as an APR function. */
            m->mmap = apr_palloc(reqpool, sizeof(apr_mmap_t));
            memcpy(m->mmap, mm, sizeof(apr_mmap_t));
            m->mmap->cntxt = reqpool;
            apr_pool_cleanup_kill(curpool, mm, mmap_cleanup);
            apr_pool_cleanup_register(reqpool, mm,
                                      mmap_cleanup, apr_pool_cleanup_null);
        }
        else {
            /* if the pools are disjoint, though,
             * we have to do ugly things. */
            apr_file_t fd;
            void *addr;

            if (apr_file_open(&fd, m->filename, APR_READ|APR_BINARY,
                                                0, reqpool) == APR_SUCCESS) {
                /* we have to switch to reopening the file into the requested
                 * pool, since we can't get any guarantees as to which pool
                 * will live longer. */
                /* XXX: there is no m->filename or m->absoffset yet,
                 * but pretend there is */
                apr_bucket_file_make(b, &fd, (m->absoffset+b->start),
                                     b->length, reqpool);
            }
            else if ((rv = apr_mmap_offset(&addr, m->mmap, b->start))
                                                     == APR_SUCCESS) {
                /* if the file open call failed (why would it ever?) we have
                 * no choice but to use the old method of copying the damned
                 * thing in. I think it should go to the heap and not into
                 * the pool, though.  It could potentially be very very big,
                 * and we don't want to grow our pool that much, since the
                 * total memory allocated never shrinks back down even
                 * after the pool goes away. */
                apr_bucket_heap_make(b, addr, b->length, 1, NULL);
            }
            mmap_destroy(m);
        }
    }
    return rv;
}

--------------------------------------------------------------
   Cliff Woolley
   [EMAIL PROTECTED]
   Charlottesville, VA


Reply via email to