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 -------------------------------------------------------------- Cliff Woolley [EMAIL PROTECTED] Charlottesville, VA