httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <>
Subject Re: Optimizing dir_merge()
Date Thu, 16 Aug 2001 01:36:08 GMT
From: "Brian Pane" <>
Sent: Wednesday, August 15, 2001 8:08 PM

> William A. Rowe, Jr. wrote:
> >Here's my take on the dir_merge patch I offered up.  Please review for sanity.
> >
> Thanks!  This looks clear and complete to me.
> There's one point at the end where I disagree, though it may be due to
> a bad assumption on my part.  Here's the item in question:
> [...]
> >Caching Considerations
> >----------------------
> >
> >The key point within Apache is; a given per-dir config cannot be trusted after a

> >subsequent merge_dir_configs callback in the same pool.
> I wouldn't have drawn this conclusion.  If your per-dir config is being passed as
> the 'base' to a subsequent merge_dir_config callback, it should be unharmed afterward
> because the callback must treat the base as const.  It's okay for the callback to
> use a very liberal definition of constness if needed for performance reasons; e.g.,
> it can increment a reference count in the base in support of copy-on-write logic.
> But from the perspective of the caller, passing a cached per-dir config as the
> base to a merge_dir_configs callback shouldn't change the semantics of the data
> in that per-dir config.
> What am I missing?

"... in the same pool."

If the caller passes a different pool to merge_dir_configs, they can be certain that
the base is untouched, as are all the members of base.

The optimization I proposed is this;  if the caller passes the same pool (as dir_walk
would, potentially many times), then the 'optimized' module is free to build upon it's
earlier efforts, e.g. adding or removing elements, whatever.  So a typical request
(I ment to put this in the docs...) is

Call Graph

  cache1 = merge_dir_configs(cache_pool_1, server-wide-base, entry-"/")

    Because cache_pool_1 is different than the cmd->pool for server-wide-base, the caller
    must be able to trust cache1 to be a copy, and server-wide-base and entry-"/" must
    be undisturbed.  Presuming cache1 is preserved, and cache_pool_1 is a new sub-pool ...

  cache2 = merge_dir_configs(cache_pool_2, cache1, entry-"/www")

    Again, we trust that cache2 is a copy and cache1 and entry-"/www" were undisturbed.

    Now we begin an actual request, that discovers cache2 for /www/website/foo/why.txt

  r->per_dir_config = merge_dir_configs(r->pool, cache2, entry-"/www/website")

    Here again, r->pool isn't cache_pool_2, so we won't touch cache2 or entry-"/www/website".

  r->sub_dir_config = merge_dir_configs(r->pool, r->per_dir_config, entry-"/www/website")

    This is the key difference in optimized merges.  The r->per_dir_config argument was

    already copied to r->pool.  After this call, the original r->per_dir_config may
    manipulated by an optimized merge function!  We can trust r->sub_dir_config is correct,
    but r->per_dir_config may have been munged.  entry-"/www/website" from the cmd->pool
    still cannot be disturbed!

  r->per_dir_config = r->sub_dir_config;
  r->sub_dir_config = merge_dir_configs(r->pool, r->per_dir_config, entry-"/www/website/foo")

    Here again, the modul -may- manipulate the given r->per_dir_config!  entry-"/www/website/foo"
    from the cmd->pool still cannot be disturbed.

  r->per_dir_config = r->sub_dir_config;
  r->sub_dir_config = merge_dir_configs(r->pool, r->per_dir_config, r-"/www/website/foo/.htaccess")

    Now we read an htaccess file.  Both the per_dir_config and the discovered .htaccess configs
    may be munged to produce r->sub_dir_config, since those structures are both in our
    However, if cache-"/www/website/foo/.htaccess" (allocated in it's own .htaccess cache
    is used, that add config still could not be munged.

  r->per_dir_config = r->sub_dir_config;

    There's the request!  Now, presume we have a sub-req that matches .html - and we have
a <Files>
    block that matches.  Let's look again;

  sub_req->per_dir_config = merge_dir_configs(sub_req->pool, r->per_dir_config, file-".txt")

    Here, the r->per_dir_config was allocated from the req pool, not the sub_req pool.
 The <Files>
    entry was allocated from the cmd->pool at startup.  So this merge MUST make a copy,
and the
    main request is undisturbed.

I hope that further clarifies, I could go into other location blocks, etc, but I think this
things pretty clear.



View raw message