apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cliff Woolley <cliffwool...@yahoo.com>
Subject freelists: a slightly different approach
Date Wed, 26 Sep 2001 04:05:33 GMT

Okay, I've been thinking about this a lot today.  I think I've come up
with a better design for this freelist scheme.  The problem with the
current scheme is that it's very implementation specific... for example,
changing from SMS to the pass-in-an-int-list-number scheme required
changing the API, and the new version of the API basically implies a lot
of information about how we're implementing the free lists.  I think it
would be much better to do the following:

1) each thread that wants to use buckets must call a function called
something like "apr_bucket_freelist_init(thread_pool)"  which returns a
pointer of some opaque type.  Something like this:

apr_bucket_freelist *apr_bucket_freelist_init(apr_pool_t *thread_pool);

2) the thread must simply remember the returned pointer and pass that in
to all calls to _bucket_foo_create().

This has several advantages:

a) No child-wide initialization is required (eg, to allocate a static
array of size num_threads or whatever), because the buckets code itself
will never keep track of ALL of the apr_bucket_freelist's it has created.
It's up to each caller to remember its own.

b) Because the buckets don't have to keep a static array or any sort of
table of the apr_bucket_freelist's, the number of threads can be totally
dynamic with no pre-defined maximum number.

c) If we choose to implement freelists another way, all we have to do is
change struct apr_bucket_freelist, and the callers will be oblivious to
the change.  If I'd done it this way initially, for example, it would have
allowed us to change from SMS to the internal freelist scheme with no API
change at all.

All apr_bucket_freelist_init() has to do is allocate an
apr_bucket_freelist out of the thread_pool and initialize it (which means
allocating an initial block and so on).

As for allocation block size, I'm thinking we might have to take Ryan's
suggestion to go back to having bucket types register themselves so that
we can accurately determine the maximum size needed.  If we're going to do
that, sizeof(private_data_structs) should become one of the fields in the
apr_bucket_type_t.  Bucket types that have no private data (eg eos,
immortal) would just stick a 0 in there.  This is clearly the most
reliable way to do it, but in a way it's kind of a shame... I was so
thrilled to have gotten rid of that registration stuff the first time
around.  If anybody has other suggestions, I'm all ears...


   Cliff Woolley
   Charlottesville, VA

View raw message