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/05/03 01:40:00 UTC

Context types in APR.

Ben Hyde and I have been discussing this off line a little bit, so I am
bringing this back to new-httpd.  I am going to _try_ to summarize what
was said, so if I get it wrong Ben, please correct me.

Ben's position:

We should forget about context types.  All the stuff we were going to put
in the context type really belongs in the pool structure.  This basically
means we are adding a thread pointer, state flags, and possibly other
fields later to the current Apache pools.  His argument is that the
context abstraction is unnecessary, and we are better off just adding the
fields to the current pools.

Ben also feels ALL apr types should allow users to hang their own data off
of them.

My position:

Pools are complex in Apache, I think it is better to use the current pool
structure, and add a new type, contexts, that include the pool pointer,
the thread pointer, the state flags, and user defined data.

I do not see a need to have each apr type allow the user to hang data off
of them.

Work done so far:

Please disregard the work done so far.  I have coded each apr function to
take a context, and use it to allocate from the pool.  I stopped coding
when each function was allocating from pools, because the current work is
easy to change.  I used a standard naming system, so changing all the
current contexts into pools will require running ONE(I already have the
script) script from the roo directory.  I will not be implementing any
mroe about pools until this issue is settled, because any other work will
become much more difficult to change to the desired system.  I figured
nobody would argue that apr sould be allocating from pools instead of
using malloc/free.

That is the short summary, the actual discussion is included below for
anybody who would like to read it.

Ryan

Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> Ryan Bloom wrote:
> > 
> > Ben's position:
> > 
> > We should forget about context types.  All the stuff we were going to
> > put in the context type really belongs in the pool structure.  This
> > basically means we are adding a thread pointer, state flags, and
> > possibly other fields later to the current Apache pools.  His
> > argument is that the context abstraction is unnecessary, and we are
> > better off just adding the fields to the current pools.
> 
> -1 on that right out of the box.  A 'pool' is a 'memory pool,'
> pure and simple. 

No argument there, the pool is the pool.  My point is that
there isn't a clear role for this context thing.  This is
data struture with nothing in it - that's silly.

   - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ryan Bloom wrote:
> 
> Ben's position:
> 
> We should forget about context types.  All the stuff we were going to
> put in the context type really belongs in the pool structure.  This
> basically means we are adding a thread pointer, state flags, and
> possibly other fields later to the current Apache pools.  His
> argument is that the context abstraction is unnecessary, and we are
> better off just adding the fields to the current pools.

-1 on that right out of the box.  A 'pool' is a 'memory pool,'
pure and simple.  Do anything else with it, and you can't call it
a pool any more.  Do aught else with it, and you're hanging lots
of unnecessary baggage on a simple primitive type, baggage
that in many cases won't be used.

Pools as a portion of a larger structure (such as a context): good.
Lots of other stuff added to a pool structure: bad.  Bad bad bad.
-- 
#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>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> Ben Hyde wrote:
> > 
> > This is the classic end to end issue.  At what layer in the
> > onion is the multiplexing done?  It doesn't belong in the pool
> > it belongs on the data structure being shared.
> 
> No, it belongs on the structure to which access needs to be
> synchronised.  

I don't understand this, I say "it belongs on the data structure
being shared" and you san "structure to which access needs to
be syncrhonized"  -- isn't that the saying the same thing?

> So I back off my earlier query and submit
> instead that the lock-or-not bit belongs in the pool structure.
> It's the pool routines that will be doing the synchronising.
> When you create a pool that doesn't require synchronising,
> such as one associated with a thread object, the bit in the
> new pool structure gets set accordingly.

It's not that you couldn't put synch on the pool operations.
It's that in practice it's not an good design, because the
data structure for which the allocations is being done often
will need syncronization so you can just leave it to that
data structure, and create a pool for that data type.

My point was that you don't need two mux you only need one.

> Proper treatment of this wrt signals requires some thought.

We block signals in pools when they allocated from the shared
data structure holding large blocks of data.  Since it's short
duration that's fine.  We also syncrhonize around the data
structure that holds those blocks.

 - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ben Hyde wrote:
> 
> This is the classic end to end issue.  At what layer in the
> onion is the multiplexing done?  It doesn't belong in the pool
> it belongs on the data structure being shared.

No, it belongs on the structure to which access needs to be
synchronised.  So I back off my earlier query and submit
instead that the lock-or-not bit belongs in the pool structure.
It's the pool routines that will be doing the synchronising.
When you create a pool that doesn't require synchronising,
such as one associated with a thread object, the bit in the
new pool structure gets set accordingly.

Proper treatment of this wrt signals requires some thought.
-- 
#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>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> Ben Hyde wrote:
> > 
> >                             This would imply that all objects created
> > by APR have a pool, and a slot for user properties, i've no problem
> > with that.
> 
> I like that.

> > Would you rather write:
> >       ap_palloc(cntx, p, sizeof(foo))
> >    or ap_palloc(p, sizeof(foo))
> > for the next decade?
> 
> I'd rather call ap_palloc(cntx, sizeof(foo)).  I've been labouring
> under the assumption that it was clear that a context includes
> a pool.

Now were getting someplace.  If your willing to spell cntx "p"
maybe we've agreed. :-).

> > >    I fail to see
> > > why pools *must* be associated with one and only one thread;
> > > I maintain that they are separate, not subordinate.
> > 
> > To avoid having ap_palloc pay the cost of getting a lock on
> > every allocation.  So they have to "reside" in a thread by
> > default.
> 
> Feh.  If you have a pool subordinate to a thread object,
> note the fact that synchronisation isn't necessary.  Store
> that note in either the pool structure or the context structure
> when it's created.  (Hey, that's not a bad idea in general..)
> For pools that aren't 'part of' a thread, leave the bit clear.

This is the classic end to end issue.  At what layer in the
onion is the multiplexing done?  It doesn't belong in the pool
it belongs on the data structure being shared.  If you put it
on the pool, then you still have to put it on the shared data
structure and then each operation on the on the data structure
has to take the data structure lock, and then as it falls into
the pool it takes the pool lock.  A pool lock is entirely
redundent - a waste.

 - ben

Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:
> Ben Hyde wrote:
> > Would you rather write:
> >       ap_palloc(cntx, p, sizeof(foo))
> >    or ap_palloc(p, sizeof(foo))
> > for the next decade?
> 
> I'd rather call ap_palloc(cntx, sizeof(foo)).

If this is the case the is there any reason to have the pool type 
exposed in the APR API except a nostolga for the old API?

  - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ben Hyde wrote:
> 
>                             This would imply that all objects created
> by APR have a pool, and a slot for user properties, i've no problem
> with that.

I like that.

> Would you rather write:
>       ap_palloc(cntx, p, sizeof(foo))
>    or ap_palloc(p, sizeof(foo))
> for the next decade?

I'd rather call ap_palloc(cntx, sizeof(foo)).  I've been labouring
under the assumption that it was clear that a context includes
a pool.

> >    I fail to see
> > why pools *must* be associated with one and only one thread;
> > I maintain that they are separate, not subordinate.
> 
> To avoid having ap_palloc pay the cost of getting a lock on
> every allocation.  So they have to "reside" in a thread by
> default.

Feh.  If you have a pool subordinate to a thread object,
note the fact that synchronisation isn't necessary.  Store
that note in either the pool structure or the context structure
when it's created.  (Hey, that's not a bad idea in general..)
For pools that aren't 'part of' a thread, leave the bit clear.
-- 
#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>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> I would have done better if the relevant manuals were to hand,
> and not buried under hundreds of pounds of flower pots.  (Not
> that the manuals are especially good fertiliser.. :-)

Worse than grass clippings.

> > My style of design assumes that there is always an "object
> > model" implicit in everything.  It continues to elude my
> > thick skull what "object" the context is standing for.
> > It would seem to be standing in for a fuzzy union of
> > activity/thread/pool/thread-state and globals.
> 
> Mmm, how about the Object class in Java? :->

Ah, now that's another hypothisis about what the context object is
trying to be.  The root class of APR's object system.  That's what I
thought at first actually.  Is that what your trying to get here.  I
almost of agree with that.  This would imply that all objects created
by APR have a pool, and a slot for user properties, i've no problem
with that.

> > 2. What compelling advantage is worth the cost of
> >    passing an additional parameter to every function?
> 
> Uniformity of syntax, and complete freedom for all functions
> to call whatever else is necessary to get their jobs done.
> This allows routines in the call chain to pass it down, and
> those that need it can use it, and those that don't can
> ignore it (but propagate it).  I have an hypothetical example
> in mind, if it comes to that.

I understand that is what will happen, it's just that I want
to be convinced that this bucket brigade of parameter passing
is buying me something I need.

> > 3. Do pools need to block signals?  If so, do they
> >    need a pointer to the thread they reside in?
> 
> If you mean do pool operations need to be signal-safe, I think
> the answer is yes.  They need to be able to achieve that
> signal-safety in a stackable and modular way.

Would you rather write:
      ap_palloc(cntx, p, sizeof(foo))
   or ap_palloc(p, sizeof(foo))   
for the next decade?

I'm a conservative traditionalises here.
What's this radical cool cntx doing for me that means I have
to change from what works?

>    I fail to see
> why pools *must* be associated with one and only one thread;
> I maintain that they are separate, not subordinate.

To avoid having ap_palloc pay the cost of getting a lock on
every allocation.  So they have to "reside" in a thread by
default.

 - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ben Hyde wrote:
> 
> I did recieve one private reply to my question for examples
> in other systems.  I've now gone and looked carefully at
> the example I was given and there the "context" is actually
> many "contexts", each one is representing an object upon
> which assorted operations are being done.

I would have done better if the relevant manuals were to hand,
and not buried under hundreds of pounds of flower pots.  (Not
that the manuals are especially good fertiliser.. :-)

> My style of design assumes that there is always an "object
> model" implicit in everything.  It continues to elude my
> thick skull what "object" the context is standing for.
> It would seem to be standing in for a fuzzy union of
> activity/thread/pool/thread-state and globals.

Mmm, how about the Object class in Java? :->

> 1. Is blocking signals an operation on threads, and if
>    so why would it's state be better in the context
>    rather than the thread's state.

I can't answer this one, from lack of knowledge.  I'm barely
thread-aware, though I'm working on it.

> 2. What compelling advantage is worth the cost of
>    passing an additional parameter to every function?

Uniformity of syntax, and complete freedom for all functions
to call whatever else is necessary to get their jobs done.
This allows routines in the call chain to pass it down, and
those that need it can use it, and those that don't can
ignore it (but propagate it).  I have an hypothetical example
in mind, if it comes to that.

> 3. Do pools need to block signals?  If so, do they
>    need a pointer to the thread they reside in?

If you mean do pool operations need to be signal-safe, I think
the answer is yes.  They need to be able to achieve that
signal-safety in a stackable and modular way.  I fail to see
why pools *must* be associated with one and only one thread;
I maintain that they are separate, not subordinate.

> Alternatively maybe you could give me an example of
> a really sweet illustration where it works out nicely.

[sounds of crashing flower pots]  I'll see what I can do.. :-)
-- 
#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>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> Ben Hyde wrote:
> > 
> > No?  It would seem to me that you only need to pass a pool
> > to those functions that create objects for the API.
> 	:
> > The case, I assume, your concerned with is when the operation
> > needs scratch space to work in, but that is not returned to
> > the caller.  Apache's standard solution to that has been to
> > store a pool in the object, when it's created, for such things.
> 
> What about the case of apr_os_f(x) that works on strings, not
> APR objects?  Or something that calls apr_os_f(x) under the covers,
> but still appears to only need a string as input?  WHat if there
> *is* no APR object clearly associated with the topmost operation?

I've no problem with passing a pool directly or indirectly to
most functions when there is the slightest chance that over
time they might need our tools.

Since I think the pool has a thread pointer in it for blocking

I don't see what the remaining problem contexts is solving is.

 - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ben Hyde wrote:
> 
> No?  It would seem to me that you only need to pass a pool
> to those functions that create objects for the API.
	:
> The case, I assume, your concerned with is when the operation
> needs scratch space to work in, but that is not returned to
> the caller.  Apache's standard solution to that has been to
> store a pool in the object, when it's created, for such things.

What about the case of apr_os_f(x) that works on strings, not
APR objects?  Or something that calls apr_os_f(x) under the covers,
but still appears to only need a string as input?  WHat if there
*is* no APR object clearly associated with the topmost operation?
-- 
#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>.
Manoj Kasichainula <ma...@io.com> writes:

> BTW, I'm wary of this whole context idea, but Ken is slowly convincing
> me.
> 
> On Fri, May 07, 1999 at 01:06:17PM -0400, Ben Hyde wrote:
> > No?  It would seem to me that you only need to pass a pool
> > to those functions that create objects for the API.  For example
> > 
> >     obj = apr_obj_create(p, ...);
> > 
> > Operations that return fresh data structures should always take
> > an explicit pool since the caller should decided what pool they
> > belong in.
> 
> The main problem here is that there might be APR functions that take
> no APR-created arguments. I didn't believe this was even possible
> until Ken mentioned the canonical_filename stuff. This is definitely a
> portability layer piece, and if demonical_filename retains its current
> form, then it will take a string and return a string. How do we
> support such an operation unless we pass in a pool/context?

Sure, there might be a problem with operations on things too simple
to have the overhead of object, but these operations can take the pool.

> There are answers of course. One is to make sure you *always* operate
> on APR-created objects. In the case of demonical_filename, create
> apr_string_t and do all our string operations through it. Qt does
> this, and I don't like it.

The design pattern where some suites of operations take a manager_object
for the class of things they are working on hasn't arisen in Apache
to date.  This usually arises because you want a set, say of already
established connections to the database server.  Sometimes people do
it just to get what we already have with pools a nice memory management
scheme.  So I wouldn't think that it would be necessary to create a
string_manager thingy and pass it around, but yeah pass a pool if there
is any chance the operation will need space.

> Another answer is to handle files like Java does, which is to create a
> Filename object (called File in Java) which is created from the string
> of the filename. Then, demonical_filename would operate on this
> Filename object, and so would all the APR file I/O routines. Is this
> an acceptable solution for every case that resembles
> demonical_filename? I personally don't mind it, but I'm sure others
> will scream loudly.

If you need an object, make it.  Creating a wild card object doesn't
reduce in any interesting way the cases that need one.

 - ben

Re: Context types in APR.

Posted by Manoj Kasichainula <ma...@io.com>.
BTW, I'm wary of this whole context idea, but Ken is slowly convincing
me.

On Fri, May 07, 1999 at 01:06:17PM -0400, Ben Hyde wrote:
> No?  It would seem to me that you only need to pass a pool
> to those functions that create objects for the API.  For example
> 
>     obj = apr_obj_create(p, ...);
> 
> Operations that return fresh data structures should always take
> an explicit pool since the caller should decided what pool they
> belong in.

The main problem here is that there might be APR functions that take
no APR-created arguments. I didn't believe this was even possible
until Ken mentioned the canonical_filename stuff. This is definitely a
portability layer piece, and if demonical_filename retains its current
form, then it will take a string and return a string. How do we
support such an operation unless we pass in a pool/context?

There are answers of course. One is to make sure you *always* operate
on APR-created objects. In the case of demonical_filename, create
apr_string_t and do all our string operations through it. Qt does
this, and I don't like it.

Another answer is to handle files like Java does, which is to create a
Filename object (called File in Java) which is created from the string
of the filename. Then, demonical_filename would operate on this
Filename object, and so would all the APR file I/O routines. Is this
an acceptable solution for every case that resembles
demonical_filename? I personally don't mind it, but I'm sure others
will scream loudly.

-- 
Manoj Kasichainula - manojk at io dot com - http://www.io.com/~manojk/
"Don't. You're too young to experience that much pain." -- Cmdr. Susan
  Ivanova, Babylon 5

Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
Ryan Bloom <rb...@raleigh.ibm.com> writes:

> > Can one of the advocates of this - add another parameter
> > for 'stuff' to every APR function - please respond to
> > my questions.
> 
> First of all, we MUST add a parameter to every apr function regardless of
> whether it is a context or a pool.  The reason for this, is that we do not
> want to rely on malloc/free to allocate memory.  Right now, contexts have
> a pool in them, so this takes care of this.  I would love to say the
> context/pool only needs to be sent to functions that allocate memory, but
> I don't know what other platforms will require in the way of helper
> structures, so although I could limit the passing to functions that need a
> pool in UNIX, what about OS/2, windows, etc..

No?  It would seem to me that you only need to pass a pool
to those functions that create objects for the API.  For example

    obj = apr_obj_create(p, ...);

Operations that return fresh data structures should always take
an explicit pool since the caller should decided what pool they
belong in.

The case, I assume, your concerned with is when the operation
needs scratch space to work in, but that is not returned to
the caller.  Apache's standard solution to that has been to
store a pool in the object, when it's created, for such things.

That design pattern, the one that means we do r->pool a lot,
works.  I don't see any reason to change it.  Changing it
will ripple thru everything.

Partially as an aside, I'll point out that I often use this
cliche.

   ap_pool *scratch_pool = ap_make_sub_pool(obj->pool);
   ...
   ap_destroy_pool(scratch_pool);

I.e. there is free operation in the pool abstraction.

> > 
> > 1. Is blocking signals an operation on threads, and if
> >    so why would it's state be better in the context 
> >    rather than the thread's state.
> 
> It really isn't a thread operation.  Blocking signals MAY be necessary in
> non-threaded programs to keep other processes from interupting that
> function.

Well even "non-thread" programs have a single thread.  Threads are stacks,
and signals are directed at stacks - right?  If we do the work to allow
the thread handling a request to be interupted when we believe that's
the right thing to do.  Work that requires a great deal of care.  Then
clearly we will want to interupt/signal/unwind as an operation on 
individual threads.

> It is more an operation on apr than an operation on threads.

This is the context in it's role as "globals" right?
If you need a data structure to hold state that is "Mr. Apr"
that's ok by me, but I don't think you need to pass it to
every routine.  The routines are operations on objects, and
those objects can have back pointers to the data structures
they reside in  them when they happen to need that.

> > 2. What compelling advantage is worth the cost of 
> >    passing an additional parameter to every function?
> 
> As I said above, allocating memory requires this parameter.  I could put
> it only in the paremeter list to the creation function, and then store the
> pool pointer in the structure, 

Yes, that's what I think we have been doing and I don't see why it's
a broken design.

> but I don't believe this allows for the
> flexibility for future growth that contexts do.

Still yearning for something that get's be excited enought to want to
change from the current approach.

> > 3. Do pools need to block signals?  If so, do they
> >    need a pointer to the thread they reside in?
> 
> Pools do need to be able to block signals, at least in some places.  They
> do not need a pointer to the thread they reside in though.  The thread is
> unnecessary, and what do we assign the pointer to in a non-threaded case?

In the non thread case the number of threads doesn't go to zero it goes
to one - you assign it to that thread.

Pools reside in threads.  If two threads wish to share a single pool they
must multiplex their access.

> Proof to these two answers can be found in 1.3.X tree of Apache.  We call
> block_alarms and unblock_alarms in the pool code.  This increments a
> variable, and when we get a signal, we check that varible.  This is on a
> NON-THREADED server, so it seems to me that either we are wasting cycles,
> or this is a needed ability (Or, I haven't reviewed the code thoroughly
> enough).

This is the correct reading of the code.  It reflects the fact that in that
server we made no attempt to direct signals at individual threads.  

The desire (possible hopeless) that we can enable the interupting of
the threads handling requests to put them out of their misery in some
carefully crafted but oh so common situations makes it very desirable
to move that counter from a global into the thread data structure.

This would be done, persumably, by having stating a default
presumbably accepting_signals for the request handling threads.
Modules could then override this when they are unable to implement
signal handling in a reasonable way.  We might even put flags in the
module struct to advise the module hook invoking routines how to
establish the blocking state during the calls backs.

> 
> HTH,
> 
> Ryan

 - ben

Re: Context types in APR.

Posted by Ryan Bloom <rb...@raleigh.ibm.com>.
> Can one of the advocates of this - add another parameter
> for 'stuff' to every APR function - please respond to
> my questions.

First of all, we MUST add a parameter to every apr function regardless of
whether it is a context or a pool.  The reason for this, is that we do not
want to rely on malloc/free to allocate memory.  Right now, contexts have
a pool in them, so this takes care of this.  I would love to say the
context/pool only needs to be sent to functions that allocate memory, but
I don't know what other platforms will require in the way of helper
structures, so although I could limit the passing to functions that need a
pool in UNIX, what about OS/2, windows, etc..

> 
> 1. Is blocking signals an operation on threads, and if
>    so why would it's state be better in the context 
>    rather than the thread's state.

It really isn't a thread operation.  Blocking signals MAY be necessary in
non-threaded programs to keep other processes from interupting that
function.  It is more an operation on apr than an operation on threads.

> 2. What compelling advantage is worth the cost of 
>    passing an additional parameter to every function?

As I said above, allocating memory requires this parameter.  I could put
it only in the paremeter list to the creation function, and then store the
pool pointer in the structure, but I don't believe this allows for the
flexibility for future growth that contexts do.

> 3. Do pools need to block signals?  If so, do they
>    need a pointer to the thread they reside in?

Pools do need to be able to block signals, at least in some places.  They
do not need a pointer to the thread they reside in though.  The thread is
unnecessary, and what do we assign the pointer to in a non-threaded case?
Proof to these two answers can be found in 1.3.X tree of Apache.  We call
block_alarms and unblock_alarms in the pool code.  This increments a
variable, and when we get a signal, we check that varible.  This is on a
NON-THREADED server, so it seems to me that either we are wasting cycles,
or this is a needed ability (Or, I haven't reviewed the code thoroughly
enough).

HTH,

Ryan


Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
Since I have veto'd this context thing the responsiblity
falls to me to work to resolve the issue.  But I'm
at a bit of a lost how to proceed to that end since the
questions I'm asking don't seem to be getting awnsered.

I did recieve one private reply to my question for examples
in other systems.  I've now gone and looked carefully at
the example I was given and there the "context" is actually
many "contexts", each one is representing an object upon
which assorted operations are being done.

My style of design assumes that there is always an "object
model" implicit in everything.  It continues to elude my
thick skull what "object" the context is standing for.
It would seem to be standing in for a fuzzy union of
activity/thread/pool/thread-state and globals.

Can one of the advocates of this - add another parameter
for 'stuff' to every APR function - please respond to
my questions.

1. Is blocking signals an operation on threads, and if
   so why would it's state be better in the context 
   rather than the thread's state.
2. What compelling advantage is worth the cost of 
   passing an additional parameter to every function?
3. Do pools need to block signals?  If so, do they
   need a pointer to the thread they reside in?

Alternatively maybe you could give me an example of
a really sweet illustration where it works out nicely.

 - ben

Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
> ... contexts ... I see them as a place to control APR's behavior, and a
> place for users to put their own data.

1. control APR's behavior

What behavior does APR have that is not part of the objects
that APR implements.  If your controling the behavior of a
thread, then pass a thread object.  If you controling the
behavior of a file pass a file object.  If the operations on
object X require access to object Y then store Y in a field
of X or pass X as a parameter to that operation.

I'm uncertain what you mean "cancel."  Is this not an operation
on a thread?

2. place for user data.

Why would APR need access to user data except to provide a way
for users to extend it's types?  Why would the users want to
use your wild card place for data rather than his own?



Can you point me to another system with a context like abstraction
so I might be able to build some sympathy for what I'm currently
seeing as just random "innovation."

Do you believe that the apache module methods will all change
to take this additional parameter?

  - ben

Re: Context types in APR.

Posted by Ryan Bloom <rb...@raleigh.ibm.com>.
> I'm -1 on contexts until somebody can explain to me what they are for.
> 
> I am NOT saying use pools as a junk yard, I'm accusing contexts
> of being a junk yard that is holding state that belongs elsewhere
> 
> My position: if your going to add an additional parameter to every
> single routine in the system then you had better have a DAMN GOOD
> description of what it is.
> 
> I've been thru every slot in this current proposal and shown they
> are unnessary, in most cases a mistake.  I now think this is just
> fuzzy thinking.
> 
> All routines are methods on objects.  Those objects should contain 
> the state required or if not the state should be a parameter.

I'll try to clear things up a bit from my POV.  I don't see contexts as a
junk yard, I see them as aplace to control APR's behavior, and a place for
users to put their own data.

Some states are across objects.  For example, whether APR routines should
be cancelable for the current application.  In Apache, the answer is no
the programmer shouldn't be able to cancel a thread while it is in an APR
function.  This may not be true of other applications, or even of some
Apache modules (e.g.:  A module that spawns it's own process in the
initializer callback may want to be able to cancel it's own threads).  It
could be argued easily, that this belongs in the thread type, but then we
have to pass a thread to each apr function.  We are now back to where do
we put the thread pointer, in a pool or in a context.

But how about should an APR function be signal safe?  Where does that flag
belong.  It isn't really a thread decision, because we have
(un)block_alarms in the process-only Apache, and that is what this falg is
meant to replace. (The name may not be great, I haven't given the naming a
great deal of thought.)

Regardless of what we do, we HAVE to pass something to every apr function.
That something MUST have access to a pool pointer.  Without this, we will
be calling malloc/free combinations in APR, and that is a performance hit
I don't think we want to suffer.  If we can all agree that a pool must
somehow get to the APR layer, then we have to decide if it is the only
thing that must get into the APR layer, or if there is something else we
may want down there.  If there is something else we want to have in APR,
it is my opinion that adding that extra stuff to pools is the wrong way to
go.

> > Ben also feels ALL apr types should allow users to hang their own data off
> > of them.
> 
> Yes I do, except those that are always compile time constants.

I guess I am trying to figure out why anybody would want to hang data off
the directory structure, or the file structure.  The only one I can see
this being an issue for, is the thread structure (for thread local
storage).

> Would you argue that threads shouldn't have a place for users to hang
> additional state off of?

No.  I believe users do need a place in threads to hang their data.  I
haven't done ANY work with threads yet.  When I get to the thread stuff,
this will be put in place.

> In anycase it's a fair question.  Read the thread "Subject: tables
> with binary data.." in nh.9903.  It's a fine example of how much of
> pain it is when people design a data structure that spans some
> activity and they assume that the users of that data structure will
> have no need to annotate it with data specific to the task they are
> working on.  This is particularly true of data structures that have
> user defined call backs.

That's not a fair comparison IMO.  Tables are currently in APR, but they
were ported directly from the Apache code, so no more work was done on
them IIRC.  Most of the current APR code/work has been on creating a
run-time that allows us to use the same calls on different platforms.
Those data types don't need a place for users to hang their data off of in
most cases (threads being the most obvious exception).

I have yet to see a basic run-time library that allows users this option,
and I have yet to see a reason for putting it into most APR types.

> 
> Currently when I write modules if I want to annotate the request, the
> connection, the uri, etc. etc. during my handling of the request I
> have to build out of band hash tables to do it.  Entirely because the
> core forgot to provide a place for me to store my mark ups on the task
> at hand.
> 
> Since I'd argue that you can't predict which APR types will, in the
> fullness of time, have callback hooks invented for them then it's
> best to just put the a few bytes in all of them so users can refine
> them.

I guess it is my opinion that APR types, for the most part, should be
handled just like any other basic data type.  The are only more complex so
that they will work across platforms.

Of course, most of the thinking I have done aobut this topic has been in
regard to the APR repalcements for basic data types.  That is what I am
most concerned with, and that is the first step to getting the hybrid
Apache to finally be crosee-platform again.  The extra stuff that has come
from the Apache code, I haven' spent too much time thinking about, so
maybe I am missing something important there.  I just don't see a reason
to add user defined data types from the basic data structures.

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>.
Ryan Bloom <rb...@raleigh.ibm.com> writes:

> Ben Hyde and I have been discussing this off line a little bit, so I am
> bringing this back to new-httpd.  I am going to _try_ to summarize what
> was said, so if I get it wrong Ben, please correct me.
> 
> Ben's position:
> 
> We should forget about context types.  All the stuff we were going to put
> in the context type really belongs in the pool structure.  This basically
> means we are adding a thread pointer, state flags, and possibly other
> fields later to the current Apache pools.  His argument is that the
> context abstraction is unnecessary, and we are better off just adding the
> fields to the current pools.

I try not to let other people's summaries of my positions act as
flame bait.

I'm -1 on contexts until somebody can explain to me what they are for.

I am NOT saying use pools as a junk yard, I'm accusing contexts
of being a junk yard that is holding state that belongs elsewhere

My position: if your going to add an additional parameter to every
single routine in the system then you had better have a DAMN GOOD
description of what it is.

I've been thru every slot in this current proposal and shown they
are unnessary, in most cases a mistake.  I now think this is just
fuzzy thinking.

All routines are methods on objects.  Those objects should contain 
the state required or if not the state should be a parameter.

> Ben also feels ALL apr types should allow users to hang their own data off
> of them.

Yes I do, except those that are always compile time constants.

> My position:
> 
> ...
> 
> I do not see a need to have each apr type allow the user to hang data off
> of them.

Would you argue that threads shouldn't have a place for users to hang
additional state off of?

In anycase it's a fair question.  Read the thread "Subject: tables
with binary data.." in nh.9903.  It's a fine example of how much of
pain it is when people design a data structure that spans some
activity and they assume that the users of that data structure will
have no need to annotate it with data specific to the task they are
working on.  This is particularly true of data structures that have
user defined call backs.

Currently when I write modules if I want to annotate the request, the
connection, the uri, etc. etc. during my handling of the request I
have to build out of band hash tables to do it.  Entirely because the
core forgot to provide a place for me to store my mark ups on the task
at hand.

Since I'd argue that you can't predict which APR types will, in the
fullness of time, have callback hooks invented for them then it's
best to just put the a few bytes in all of them so users can refine
them.

> Work done so far:
> 
> Please disregard the work done so far.  ...

I'm trying...

 - ben

Re: Context types in APR.

Posted by Ben Hyde <bh...@pobox.com>.
Rodent of Unusual Size <Ke...@Golux.Com> writes:

> Greg Stein wrote:
> > 
> > Can anybody explain why another context would ever be created?
> 
> As an example: within the routine library itself, if/when a
> library routine needs a private but unbounded work area/whatever
> that it intends to release at exit.  Given the current
> implementation of pools (no free()), assuming that each
> routine can leave droppings all over its caller's context
> isn't very friendly -- the routine has no idea what the
> parent context's persistence is, and shouldn't care.

How is this different than a pool? - ben

Re: Context types in APR.

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Greg Stein wrote:
> 
> Can anybody explain why another context would ever be created?

As an example: within the routine library itself, if/when a
library routine needs a private but unbounded work area/whatever
that it intends to release at exit.  Given the current
implementation of pools (no free()), assuming that each
routine can leave droppings all over its caller's context
isn't very friendly -- the routine has no idea what the
parent context's persistence is, and shouldn't care.
-- 
#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 Greg Stein <gs...@lyra.org>.
Ryan Bloom wrote:
...
> Ben's position:
> 
> We should forget about context types.  All the stuff we were going to put
> in the context type really belongs in the pool structure.  This basically
> means we are adding a thread pointer, state flags, and possibly other
> fields later to the current Apache pools.  His argument is that the
> context abstraction is unnecessary, and we are better off just adding the
> fields to the current pools.
> 
> Ben also feels ALL apr types should allow users to hang their own data off
> of them.
> 
> My position:
> 
> Pools are complex in Apache, I think it is better to use the current pool
> structure, and add a new type, contexts, that include the pool pointer,
> the thread pointer, the state flags, and user defined data.
> 
> I do not see a need to have each apr type allow the user to hang data off
> of them.

+1 on the Ryan-position.

I would like to see a clearer definition of a context, though. IMO, I
see a context as a replacement for global and per-thread variables.
Therefore, it seems there are only two contexts: global and per-thread.
Can anybody explain why another context would ever be created? (and
don't say to create another pool: a new pool should always be a sub-pool
of another, falling back to the "global" pool)

Cheers,
-g

--
Greg Stein, http://www.lyra.org/