You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ryan Bloom <rb...@raleigh.ibm.com> on 1999/04/29 22:32:55 UTC
Context types in apr
I just committed a patch which implements contexts in apr. I forgot they
hadn't been mentioned in the docs originally posted about apr a while ago
until somebody reminded me. So, I am going to try to remedy this situation
by discussing them now. The reason they weren't posted, was because we
couldn't decide on a good implementation. As APR has grown, the
implementation has become much more obvious. So, here it goes.
What is a context. A context is a structure that will be passed to EVERY
apr function. It allows us to do a few really nice things.
1) We store pools in the context. This way, we always allocate out of
pools
2) The programmer who is using apr has the ability to store their own
data with a context. This is basically replicating thread-local storage
in a VERY portable way, and it doesn't incur the performance penalty that
most thread-local storage does.
3) The programmer can tune apr during at run-time to have apr functions
be safe for signals or asynch thread cancelation. The tuning will allow
programmers who want or need these abilities to get them, without causing
a huge performance hit for anybody who doesn't want them.
Contexts are also easily extensible without requiring huge changes
throughout the code. If there is some run-time constant that all threads
need to have, but we would rather not use a global variable for, a
context allows for this easily, simply by putting that data in the
programmer defined structure.
This is also useful because we can now change the implementation within
apr without needing to change the API. For example, if an apr function
needs to allocate memory at some point in the future, but it doesn't need
to now (maybe Linux gives us a faster system call, but it requires a new
structure), we don't need to change the API to the apr function, because
it will automatically have a pool from which to allocate that structure.
This also takes away potential programmer error when creating threads
and/or processes. Because pools are now apr structures, when I create an
apr_thread, I know I also want to create a new pool for it. This was
discussed earlier this week on new-httpd. By adding this context, I can
garauntee that each time I create a new thread, I WILL create a new pool
for it.
Any thoughts/comments? I can always remove the context structures if the
group thinks they aren't needed.
Ryan
_______________________________________________________________________
Ryan Bloom rbb@raleigh.ibm.com
4205 S Miami Blvd
RTP, NC 27709 It's a beautiful sight to see good dancers
doing simple steps. It's a painful sight to
see beginners doing complicated patterns.
Re: Context types in apr
Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ryan Bloom wrote:
>
> Any thoughts/comments? I can always remove the context structures
> if the group thinks they aren't needed.
I'm in favour of this. Since the contexts will need to be created
somehow, I envision something like the following (pseudocode) being
possible:
apr_context_t *ctx;
apr_context_t *subctx;
typedef struct {
int size;
char *ptr;
} foo;
foo *memp;
ctx = apr_create_context(NULL); /* create a 'top-level' context */
subctx = apr_create_context(ctx);/* a 'sub-pool'-like thing */
:
fp = apr_file_open(subctx, ...);
memp = apr_alloc(context, sizeof(foo));
memp->size = 5;
memp->ptr = apr_alloc(context, memp->size);
strcpy(memp->ptr, "1234");
status = apr_set_uservar(context, memp)
:
memp = apr_get_uservar(context);
:
apr_destroy_context(ctx);
It's very easy to think of these contexts as though they were
pools, though they're actually pools-plus.
I see the context pointer being passed to *all* APR functions,
whether the functions need it or not, for two reasons:
1. Uniformity of semantics
2. Something the function itself calls may need it, now or later
--
#ken P-)}
Ken Coar <http://Web.Golux.Com/coar/>
Apache Software Foundation <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>
Re: Context types in apr
Posted by Ben Hyde <bh...@pobox.com>.
Ryan Bloom <rb...@raleigh.ibm.com> writes:
> >
> > This is good, but I don't think it's just exactly
> > right.
> >
> > Every operation needs to have access to a pool.
> > Every operation needs to have access to the thread.
>
> I'm not sure I agree with this second statement. Why does a file open
> operation need access to a thread?
Just to pick an example, operations need to be able to guard against
thread destruction, i.e. the decendent of the current
ap_{block,unblock}_alarms.
> I think a thread pointer would be the perfect thing to go into the
> programmer defined area.
I think there ought to be a place in all the apr data structures
for thier users to hand additional application specific data.
See: <http://zap.ne.mediaone.net/p/p/properties/>
So there ought to be a APR API user area in pools, and in threads.
The design tangle here is exactly what the topology between the
apr data structures should be that is useful and necessary for
inside and outside apr.
> > Both threads and pools are used to encapsulate some
> > activity, so they look similar. But pools should
> > be allowed to out number threads.
>
> That was my original plan. Although a context and thus a pool would be
> created for each pool
APR object, of course, all encapsulate some "activity".
We have a hierarchy of pools, and a hierarhcy of threads.
I think it's reasonably clear that branchs in the tree
of pools reside in nodes of the hierarhcy of threads.
I just can't see a difference between contexts and pools.
> it would be possible and in fact necessary that we
> have contexts that are not tied to pools. The first thing any apr
> function should do is call apr_initialize, and that will create a context
> that isn't tied to any thread. This context ends up being the parent
> context of all other contexts.
But it could just as well return the root pool and that pool
can give it access to the root thread.
> I think all of your ideas make sense for Apache, but I do not believe
> keeping a thread pointer in the pool on context itself is a good idea. I
> was envisioning the base context (one without any user data) as a place
> for any flags or data structures that apr needs to modify it's behavior.
Like I say - I think all the operations need a pool and a thread.
They need the pool to get space, and they need the thread to get
the thread mux and to create fresh threads.
- ben
---
"WARNING: Your operating system is unfamiliar." -- Bongo
Re: Context types in apr
Posted by Ryan Bloom <rb...@raleigh.ibm.com>.
>
> This is good, but I don't think it's just exactly
> right.
>
> Every operation needs to have access to a pool.
> Every operation needs to have access to the thread.
I'm not sure I agree with this second statement. Why does a file open
operation need access to a thread? I can see each Apache operation
possibly needing access to a thread, but do we want to make every apr
function have the same requirement.
I think a thread pointer would be the perfect thing to go into the
programmer defined area.
>
> Both threads and pools are used to encapsulate some
> activity, so they look similar. But pools should
> be allowed to out number threads.
That was my original plan. Although a context and thus a pool would be
created for each pool, it would be possible and in fact necessary that we
have contexts that are not tied to pools. The first thing any apr
function should do is call apr_initialize, and that will create a context
that isn't tied to any thread. This context ends up being the parent
context of all other contexts.
I think all of your ideas make sense for Apache, but I do not believe
keeping a thread pointer in the pool on context itself is a good idea. I
was envisioning the base context (one without any user data) as a place
for any flags or data structures that apr needs to modify it's behavior.
Ryan
_______________________________________________________________________
Ryan Bloom rbb@raleigh.ibm.com
4205 S Miami Blvd
RTP, NC 27709 It's a beautiful sight to see good dancers
doing simple steps. It's a painful sight to
see beginners doing complicated patterns.
Re: Context types in apr
Posted by Ben Hyde <bh...@pobox.com>.
This is good, but I don't think it's just exactly
right.
Every operation needs to have access to a pool.
Every operation needs to have access to the thread.
Both threads and pools are used to encapsulate some
activity, so they look similar. But pools should
be allowed to out number threads.
For example I often write code like this:
foo *create_foo(ap_pool *p, ...)
{
ap_pool *foo_pool = create_sub_pool(p);
foo *new_foo = (foo *)ap_alloc(p, sizeof(foo));
foo->pool = foo_pool;
ap_register_cleanup(foo, foo_cleaner);
foo-> ...
}
void *destroy_foo(foo *f)
{
ap_destroy_pool(f);
return NULL;
}
Then foo can live for a period shorter than it's
parent pool and when it finishes I can clean up
the memory the activites around foo needed.
I'd lean toward just being sure that every datum
has a pool pointer in it and that ever pool has
a pointer to the thread. Then you only need to
pass a pool to the creation routines, and a
since the other operations on that datum can
use it's pool for their temporary needs.
gum *gum_create(ap_pool *p, flavor x)
{
gum *g = (gum *)ap_alloc(p, sizeof(gum));
g->pool = p;
g->flavor = x;
}
void *gum_chew(gum *g)
{
body *b = (body *)(g->pool->thread->parent->state);
mouth *m = b->mouth;
lock *lk = m->lock;
lock(lk);
mouth_chew(m, g);
unlock(lk);
}
In this example the thread might implement the afternoon
while the pool passed to gum_create might only span
the afternoon snack.
- ben