You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Justin Erenkrantz <je...@ebuilt.com> on 2001/07/15 19:10:42 UTC

Pools in threads WAS Re: Terminating threads in a process, WAS: RE: [PATCH] Problems with MPM threaded

On Sun, Jul 15, 2001 at 07:16:35PM +0200, Sander Striker wrote:
> > Fair enough. It's just that in order to opt-out of the child-pool creating
> > process in apr_thread_create, we're going to have to add a parameter
> 
> Why are we so desperate in opting out the child-pool creation?
> I don't really have problems with a child pool for each thread. Actually,
> it will make the dynamic locking a lot easier to implement if it stays.

The problem is that apr_thread_create is completely bogus right now.

The child thread has no access to that pool in apr_thread_t->pool.
If you want a pool in the thread, you should be creating inside
of the thread's function not in apr_thread_create.

And, apr_thread_exit call should *not* be taking in an apr_thread_t
because the child doesn't have access to that either.  

We're enforcing the use of global variables to work around this and 
that's plain wrong.  -- justin


RE: DCEthreads (was Re: Pools in threads)

Posted by Sander Striker <st...@apache.org>.
>>> And, it would add 3.5 million lines of code to APR.  
>> 
>> Nah. It would add the lines to add thread cancellation.  The
>> 3.5 million LOC is the _entire_ dce rpc codebase. Only part
>> of that is the dce threads library. And, I believe there are
>> some old dce/rpc team members in our midst who could know how
>> this all fit together. I could be wrong though.
> 
> [warning: tangent -- i changed the subject appropriately]
> 
> I must admit that it sounds tantalizing, but I have a comment and a
> question:
> 
> - It appears that the Free DCE package quoted above is under the GPL
>   and is therefore incompatible with the Apache License.

Yes.  However, I wasn't suggesting using or copying code from the
free dce package.  You can merely examine it and decide whether
implementing thread cancellation in such a way is something we want
in APR.  Then, you write your own implementation.

Furthermore, I would like to compare the Free DCE threads implementation
with the DCE/RPC threads implementation.  Then pick the best design
decisions from both.

> - What is meant by "*emulated* on top of POSIX threads"? What are the
>   tradeoffs, if any, compared to a implementation that is native to
>   the OS?

Sander


DCEthreads (was Re: Pools in threads)

Posted by Aaron Bannert <aa...@ebuilt.com>.
On Mon, Jul 16, 2001 at 09:05:40AM +0200, Sander Striker wrote:
> > On Mon, Jul 16, 2001 at 01:54:14AM +0200, Luke Kenneth Casson 
> > Leighton wrote:
> > > ah, yes, but it _is_ supported by DCEthreads - see
> > > http://sourceforge.net/projects/freedce which provides,
> > > horror-of-horrors, thread cancellation *emulated* on
> > > top of POSIX threads.
> > [snip, snip]
> > > ... but what i am basically saying is, on NT and Unix,
> > > thread cancellation _is_ possible, it's just that i
> > > think you might not be too happy about the coding-route
> > > you might have to take to _do_ it :) :)
> > 
> > Possible, but not robust.  
> 
> DCE/RPC is _very_ robust. That being the case its underlying
> mechanisms are very likely to be robust too.
> 
> > And, it would add 3.5 million lines of code to APR.  
> 
> Nah. It would add the lines to add thread cancellation.  The
> 3.5 million LOC is the _entire_ dce rpc codebase. Only part
> of that is the dce threads library. And, I believe there are
> some old dce/rpc team members in our midst who could know how
> this all fit together. I could be wrong though.

[warning: tangent -- i changed the subject appropriately]

I must admit that it sounds tantalizing, but I have a comment and a
question:

- It appears that the Free DCE package quoted above is under the GPL
  and is therefore incompatible with the Apache License.

- What is meant by "*emulated* on top of POSIX threads"? What are the
  tradeoffs, if any, compared to a implementation that is native to
  the OS?

-aaron


Re: Pools in threads

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
> Nah. It would add the lines to add thread cancellation.  The
> 3.5 million LOC is the _entire_ dce rpc codebase. 

which includes about 15 separate services such as DCE/DFS,
which is actually AFS [without the bugfixes and with a
new RPC mechanism]

which you don't need, as sander says.

> Only part
> of that is the dce threads library. And, I believe there are
> some old dce/rpc team members in our midst who could know how
> this all fit together. I could be wrong though.

i'll ask.  might get a response tomorrow.

luke

RE: Pools in threads

Posted by Sander Striker <st...@apache.org>.
> On Mon, Jul 16, 2001 at 01:54:14AM +0200, Luke Kenneth Casson 
> Leighton wrote:
> > ah, yes, but it _is_ supported by DCEthreads - see
> > http://sourceforge.net/projects/freedce which provides,
> > horror-of-horrors, thread cancellation *emulated* on
> > top of POSIX threads.
> [snip, snip]
> > ... but what i am basically saying is, on NT and Unix,
> > thread cancellation _is_ possible, it's just that i
> > think you might not be too happy about the coding-route
> > you might have to take to _do_ it :) :)
> 
> Possible, but not robust.  

DCE/RPC is _very_ robust. That being the case its underlying
mechanisms are very likely to be robust too.

> And, it would add 3.5 million lines of code to APR.  

Nah. It would add the lines to add thread cancellation.  The
3.5 million LOC is the _entire_ dce rpc codebase. Only part
of that is the dce threads library. And, I believe there are
some old dce/rpc team members in our midst who could know how
this all fit together. I could be wrong though.

Sander


Re: Pools in threads

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Mon, Jul 16, 2001 at 01:54:14AM +0200, Luke Kenneth Casson Leighton wrote:
> ah, yes, but it _is_ supported by DCEthreads - see
> http://sourceforge.net/projects/freedce which provides,
> horror-of-horrors, thread cancellation *emulated* on
> top of POSIX threads.
[snip, snip]
> ... but what i am basically saying is, on NT and Unix,
> thread cancellation _is_ possible, it's just that i
> think you might not be too happy about the coding-route
> you might have to take to _do_ it :) :)

Possible, but not robust.  And, it would add 3.5 million lines 
of code to APR.  Well, we could the APROS in that many LOC.  =)
Kind of like Quake - have an OS inside of your web-server.

Thread cancellation just opens up a can of worms not because the OS
doesn't support them, but because their semantics are ill-defined.
We'd have to add cancellation points to our code.  Not going to
happen.  Well, I'm not going to do it.  I might even veto it out 
of pure spite.  =)  -- justin


Re: Pools in threads

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
On Sun, Jul 15, 2001 at 04:43:37PM -0700, Justin Erenkrantz wrote:
> On Mon, Jul 16, 2001 at 12:46:31AM +0200, Luke Kenneth Casson Leighton wrote:
> > > In order to provide a win against the current pool code in a threaded
> > > MPM, we *need* to have thread-specific SMS that have no locks or
> > > association to anything other than a simple unlocked (from APR's
> > > perspective) malloc/free (aka std) SMS.  -- justin
> > 
> > okay.
> > 
> > well... uhmmm... this is going to sound odd.  i'm not even sure
> > if it will help, because i am a bit out of my depth in understanding
> > the problem.
> > 
> > how about a 'pass-through' sms for threads?
> 
> I'm not sure I'm following you.  The thread SMS never needs locks.
 
i am not necessarily referring to locks.

if there is something _ever_ so slightly different about the
circumstances under which sms instances need to be used, then
what i am suggesting is that instead of doing this:

apr_sms_general_t
apr_sms_thread_capable_general_t
[which was what you were recommending ;)]
apr_sms_trivial_t
apr_sms_thread_capable_trivial_t

instead having a:
apr_sms_thread_wrapping_redirector_t

and use *that* to do the thread-capable-very-specific-things
that i suspect you will need to do for all-and-any SMSes,
pretty much, and that might not necessarily be locking,
which simplifies the coding needed.

> Sander was under the assumption that the parent of a thread can clean up
> a thread.  That isn't supported with POSIX pthreads (cleanly).
> Apparently, Win32 has some support for this.  This lack basically kills
> off the parent/child relationship between SMSes across threads.
 
ah, yes, but it _is_ supported by DCEthreads - see
http://sourceforge.net/projects/freedce which provides,
horror-of-horrors, thread cancellation *emulated* on
top of POSIX threads.

DCEthreads is an implementation of POSIX (draft 4) threads
which of course drastically changed from the final
release.

now, if you examine Windows NT threads, i _bet_ they
support thread cancellation properly, because they
do support thread cancellation via dce/rpc (and dcom,
which is basically an object-orientated interface on
top of dce/rpc).

why?  because, well, that's a long story.

also, take a lok at www.opengroup.org/dce, download the
88mb of the dce 1.22 source code, unpack it to its 430mb
uncompressed size [no, i'm not kidding: yes, that's right,
four hundred and thirty megabytes - 3.5 million lines of code,
i had to use xargs to do wc on them], and you will find that there is
DCEthreads supported for AIX, HP/UX, Solaris, DG/UX, SGI's Unix
(forgotten what it is!  IRIX *duh* :)

... but what i am basically saying is, on NT and Unix,
thread cancellation _is_ possible, it's just that i
think you might not be too happy about the coding-route
you might have to take to _do_ it :) :)


> pthread_cancel() gets us into all sorts of problems we don't want to 
> deal with.  It has been discussed years ago between Ryan, Dean and 
> Manoj - see around 08-1999 - "First in a long line of APR related 
> patches".  And, it isn't guaranteed to work, either (mutex acquires 
> are *not* interruptable).  In that same thread, Ryan also brings up a
> precursor to SMS.  Rather interesting thread, really.  (See
> www.apachelabs.org if you don't have a favorite new-httpd archive.)
> 
> Unless you have a clean way of killing off a thread from a parent,
> thread-based SMS must be directly parented from a basic non-locking 
> SMS (like std SMS).  
> 
> I'm open to any creative suggestions that work.  I'm just not aware 
> of any that work.  -- justin

:)


Re: Pools in threads

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Mon, Jul 16, 2001 at 12:46:31AM +0200, Luke Kenneth Casson Leighton wrote:
> > In order to provide a win against the current pool code in a threaded
> > MPM, we *need* to have thread-specific SMS that have no locks or
> > association to anything other than a simple unlocked (from APR's
> > perspective) malloc/free (aka std) SMS.  -- justin
> 
> okay.
> 
> well... uhmmm... this is going to sound odd.  i'm not even sure
> if it will help, because i am a bit out of my depth in understanding
> the problem.
> 
> how about a 'pass-through' sms for threads?

I'm not sure I'm following you.  The thread SMS never needs locks.

Sander was under the assumption that the parent of a thread can clean up
a thread.  That isn't supported with POSIX pthreads (cleanly).
Apparently, Win32 has some support for this.  This lack basically kills
off the parent/child relationship between SMSes across threads.

pthread_cancel() gets us into all sorts of problems we don't want to 
deal with.  It has been discussed years ago between Ryan, Dean and 
Manoj - see around 08-1999 - "First in a long line of APR related 
patches".  And, it isn't guaranteed to work, either (mutex acquires 
are *not* interruptable).  In that same thread, Ryan also brings up a
precursor to SMS.  Rather interesting thread, really.  (See
www.apachelabs.org if you don't have a favorite new-httpd archive.)

Unless you have a clean way of killing off a thread from a parent,
thread-based SMS must be directly parented from a basic non-locking 
SMS (like std SMS).  

I'm open to any creative suggestions that work.  I'm just not aware 
of any that work.  -- justin


Re: Pools in threads

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
> In order to provide a win against the current pool code in a threaded
> MPM, we *need* to have thread-specific SMS that have no locks or
> association to anything other than a simple unlocked (from APR's
> perspective) malloc/free (aka std) SMS.  -- justin

okay.

well... uhmmm... this is going to sound odd.  i'm not even sure
if it will help, because i am a bit out of my depth in understanding
the problem.

how about a 'pass-through' sms for threads?

all it does is to create an apr_sms_thread_passthrough() is:

memcpy(&thr_pthru, &someothersms_api);
then OVERRIDE the create function, calling the *someothersms*->create.

you then do your 'thread-specific' stuff that you need to do,
e.g. locking _whatever_, i really don't know, as a wrapper around
the someothersms.

in other words, via this technique, you can turn a non-thread-capable
SMS into a thread-safe one.

... does that sound a bit mad, but useful, or am i way off the mark.

luke

Re: Pools in threads

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Sun, Jul 15, 2001 at 07:52:46PM +0200, Sander Striker wrote:
> Can't we pass in a data structure to the thread function which has
> all the required information? The data the user wants to pass in will
> need to be in the data structure aswell ofcourse.

-0.9.  I don't like the idea of marshaling the data to the thread's
worker function.

I'm seeing the proposed marshaling like so:

struct {
 void *data;
 apr_pool_t *pool;
} apr_thread_starter_t;

void * worker_function(void *v)
{
 apr_thread_starter *ts = v;
 whatever_the_thread_really_wants_t *d = ts->data;
 ...
}

apr_thread_create(blah, blah, blah)
{
  apr_thread_starter *ts = apr_palloc(...);
  ts->data = the-data-that-user-really-wants-to-pass-in;  
  ts->sms = apr_pool_create(blah, blah, blah);

  thread_create(go call worker_function with ts as the sole argument)
}

Yuck.  

Since I'm seeing the thread SMS be completely separate from the parent
SMS, I'm just not sure why we even want to pass the sms along.  

Unless you can make a case that the thread's SMS needs to know about the
parent SMS.  If so, then we've got major problems in our SMS design.

In order to provide a win against the current pool code in a threaded
MPM, we *need* to have thread-specific SMS that have no locks or
association to anything other than a simple unlocked (from APR's
perspective) malloc/free (aka std) SMS.  -- justin


Re: Design of pools and threads

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Mon, Jul 16, 2001 at 10:58:17AM -0700, Brian Pane wrote:
>   * The parent pool should control the cleanup of its children
>     to ensure timely resource release (important for memory, but
>     even more important for file descriptors).  In the case of
>     an httpd with a high request volume, this cleanup needs to
>     happen for a request and all its subrequests right after
>     the response is sent; otherwise we

Correct except for the case of a parent/child relationship across 
threads as the parent can't cleanup the children in this case.

FWIW, I'm not talking about the SMS used for a request.  It could be 
cleaned up (i.e. reset) after the request is completed (exactly like 
it is now - no code changes).  It'd free the resources - just like now.
We're simply divorcing its ancestor (the per-thread SMS) from the 
per-process SMS.  The children of this per-thread SMS still have the 
same manner of operation as before.  -- justin


Re: Design of pools and threads

Posted by Brian Pane <bp...@pacbell.net>.
Justin Erenkrantz wrote:
[...]

>- Why do we want an independent per-thread SMS?  Because it now removes 
>  the requirement for locking.  A thread may not be reentrant upon
>  itself - executing in two places at once.  It's a thread with one flow
>  of control.  Memory allocation without the need for locking should 
>  be a good thing.  In order to scale well with threads, I believe httpd 
>  requires independent (thread-local free list) per-thread SMS.
>- Does merely having a per-thread SMS (and its associated thread-local 
>  free list) necessitate a break from its parent SMS (i.e. independent)?
>  Yes, I believe so.  If we were to assume that the per-thread SMS had 
>  a parent/child relationship to the per-process SMS, then we must now 
>  have locking.  By design, a SMS must allocate memory from its parent.
>  Since the parent SMS would now be reentrant (as the parent, it has 
>  spawned multiple threads that are executing in parallel all asking it 
>  for memory), the parent SMS must acquire a lock before allocating 
>  memory.  This lock is the very thing we are trying to avoid in the 
>  first place.  Also, when a parent/child relationship exists between 
>  two SMS, the parent may clean up the child's SMS when it is destroyed.
>- However, for reasons described above, it is impossible for the parent
>  to clean up its children threads forcibly.  The only thing the parent 
>  can do is wait for the thread to exit on its own behalf (via
>  apr_thread_join).  The parent may only make hints (such as 
>  workers_may_exit in threaded MPM) to the thread that it should exit.
>- So, would having an independent per-thread SMS break any assumptions
>  in APR or httpd?  I don't think so.  Why?  I believe that the thread
>  is a logical breaking-off point for memory allocation.  If we were to
>  assume a thread were to create a SMS when it begins, all subsequent
>  processing in that thread will use this SMS.  When this independent
>  per-thread SMS is destroyed (as the thread is exiting - remember we
>  have assumed that the thread must exit voluntarily), the memory is
>  reclaimed.  All descriptors or sockets opened during that threads'
>  life is now returned to the OS.
>
I really think we need a hybrid model that splits the two roles
of a parent in the SMS design.  One of my messages in the archives
talks about this in more detail, but the basic idea is:
  * The parent pool should control the cleanup of its children
    to ensure timely resource release (important for memory, but
    even more important for file descriptors).  In the case of
    an httpd with a high request volume, this cleanup needs to
    happen for a request and all its subrequests right after
    the response is sent; otherwise we
  * But the parent doesn't need to be where the children go
    to get blocks when they need more memory; instead, they
    should call directly to the most efficient source of memory
    that's suitable for the application (e.g., a per-thread SMS).

--Brian



Design of pools and threads

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Sun, Jul 15, 2001 at 07:20:28PM -0700, rbb@covalent.net wrote:
> Pools are by their very nature hierarchical.  That is why the relationship
> is there, and why it needs to remain there.  You can't just rely on the
> thread to cleanup itself.  Pools (and SMS's) are used for a LOT more than
> just memory allocation in the server.  They make sure that descriptors are
> closed correctly.  In some places, they are used to make sure that
> anything the child opened that isn't returned to the OS automatically is
> returned when the child goes away.
> 
> If you divorce the thread pool from the pool for the child, you WILL break
> many assumptions in the server.

Here is what I understand the situation to be.  Please correct me if 
any of my statements are incorrect.

- A parent may not terminate any child threads forcibly (via a system
  call or other mechanism).  The best mechanism we can hope for (at this
  time - again no real progress has been made on alternatives) is to
  indicate via some way that the thread can honor the request to
  terminate gracefully.
- For various safety/robustness issues, we have decided to not implement 
  a pthread_cancel()-like mechanism.  There are three reasons for this - 
  we may arbitrarily cancel the thread even if it is in the middle of an 
  important transaction and certain operations (acquiring mutexes) are
  non-cancellable.  (It is true that we could set cancellation points
  in the APR-using programs to prevent important transactions from being
  cancelled.)  Furthermore, when issuing a pthread_cancel-like call, 
  certain OSes may leak the resources of a thread.  This is the third
  consideration to implementing this option.  With all of these 
  factors in consideration, Dean, Manoj, and you (and others) decided 
  not to implement a pthread_cancel-like mechanism in APR.  I do think 
  that this was the correct decision.
- Since APR has no way of forcing a thread to exit, this agreement lives 
  entirely outside of the bounds of APR.  What I mean by this is that 
  the APR library can not provide this thread-exit mechanism 
  transparently to APR-using programs via cleanups.  Only the thread 
  itself may choose to shut down.  If the thread so wishes, it may 
  consult any mechanisms it desires (such as shared memory, sockets, 
  pipes, etc.).  But, we have no clean way for a parent to kill a child 
  thread that does not wish to exit.
- As an example of what I mean, please look at the threaded MPM.  Each 
  worker thread is in control of when they may exit, and the mechanism 
  for determining when to exit lies outside of APR (via the 
  process-local workers_may_exit variable and the POD).
- You have suggested that a thread pool has a relationship to its parent
  (from the process before thread was created).  I believe this
  assumption is invalid IF we are to attempt an independent per-thread 
  SMS.  And, I believe that a per-process memory model does not work 
  with a threaded httpd architecture.
- Why do we want an independent per-thread SMS?  Because it now removes 
  the requirement for locking.  A thread may not be reentrant upon
  itself - executing in two places at once.  It's a thread with one flow
  of control.  Memory allocation without the need for locking should 
  be a good thing.  In order to scale well with threads, I believe httpd 
  requires independent (thread-local free list) per-thread SMS.
- Does merely having a per-thread SMS (and its associated thread-local 
  free list) necessitate a break from its parent SMS (i.e. independent)?
  Yes, I believe so.  If we were to assume that the per-thread SMS had 
  a parent/child relationship to the per-process SMS, then we must now 
  have locking.  By design, a SMS must allocate memory from its parent.
  Since the parent SMS would now be reentrant (as the parent, it has 
  spawned multiple threads that are executing in parallel all asking it 
  for memory), the parent SMS must acquire a lock before allocating 
  memory.  This lock is the very thing we are trying to avoid in the 
  first place.  Also, when a parent/child relationship exists between 
  two SMS, the parent may clean up the child's SMS when it is destroyed.
- However, for reasons described above, it is impossible for the parent
  to clean up its children threads forcibly.  The only thing the parent 
  can do is wait for the thread to exit on its own behalf (via
  apr_thread_join).  The parent may only make hints (such as 
  workers_may_exit in threaded MPM) to the thread that it should exit.
- So, would having an independent per-thread SMS break any assumptions
  in APR or httpd?  I don't think so.  Why?  I believe that the thread
  is a logical breaking-off point for memory allocation.  If we were to
  assume a thread were to create a SMS when it begins, all subsequent
  processing in that thread will use this SMS.  When this independent
  per-thread SMS is destroyed (as the thread is exiting - remember we
  have assumed that the thread must exit voluntarily), the memory is
  reclaimed.  All descriptors or sockets opened during that threads'
  life is now returned to the OS.
- Furthermore, we know that the process may not exit before the children
  threads may exit.  For the entire lifetime of the thread, any 
  process-local variables in use by the threads must remain valid.  
  This is inherent in the threading model of all the operating systems 
  we encounter.  A malicious parent indeed, could reset its SMS 
  *before* allowing all of its children to exit.  But, let's not worry
  about that (or any error conditions - we're screwed anyway).
- Again, let's consider the case of the threaded MPM.  The parent of 
  the threads (i.e. child process) will only destroy the process-level 
  SMS when it calls clean_child_exit().  Any per-process open 
  descriptors are now closed as the process terminates.  This call 
  occurs after the call to apr_thread_join() on all started threads.  
  No more child threads are present when this code is called.  Again, 
  this code is correct.

I hope I now have made my position and rationale clearer.  Again, I may
have misinterpreted code or design or made blatantly wrong statements.
I heartily welcome any feedback or corrections.  I am human - 
therefore, I am usually wrong.

Respectfully yours,
Justin Erenkrantz
jerenkrantz@ebuilt.com


Re: Pools in threads WAS Re: Terminating threads in a process, WAS: RE: [PATCH] Problems with MPM threaded

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
> There is *zero* benefit to having any relationship between the 
> thread's memory pool and the parent's memory pool.  You can't cleanup 
> the thread from the parent anyway, so trust the thread to cleanup 
> itself (as well as its pool and any memory allocations).  I fail to 
> see the problem here.  Sever the imagined relationship.  The code 
> becomes simpler, too.  -- justin

coooool.  problem-solving by conventions.  follow these rules,
everything's okay.

Re: Pools in threads WAS Re: Terminating threads in a process, WAS: RE: [PATCH] Problems with MPM threaded

Posted by rb...@covalent.net.
On Sun, 15 Jul 2001, Justin Erenkrantz wrote:

> On Sun, Jul 15, 2001 at 02:33:54PM -0700, rbb@covalent.net wrote:
> > Guys, before you make comments like this, you should really read the code.
> > First of all, the thread_exit call needs to take in the thread variable.
> > Without it, platforms like OS/2 can't return values from the thread exit
> > routine.
>
> We could stipulate in APR that on OS/2 we won't return the result
> code.  Big deal.  It's not the end of the world.  And, it's only a hack
> that works in conjunction with OS/2's apr_thread_join.  OS/2 threads
> obviously don't support return codes.  APR is only as good as the
> underlying thread library.

No, because that is utterly bogus.  The whole point of APR, is to allow a
program to be written that will work on ANY platform.  There are very few
features that can't be implemented cross platform.

> If you are willing to lose the return code on OS/2, you now have OS/2
> not needing the thread structure either.  APR is a game of tradeoffs -
> this is one we should make in order to get a better API at the cost of
> something that this native OS doesn't provide anyway.

No.  APR is not a game of tradeoffs.  It has never been a game of
tradeoffs.  We only make decisions like this when it is absolutely
impossible to implement a feature on a given system.  As we have already
shown, this can be implemented.

> We should be seeing red flags everywhere because our own code isn't
> calling the apr_thread_exit() function.  Why?  The API is, uh,
> lacking.

No, that is not why we don't call apr_thread_exit.  We don't call
apr_thread_exit, because we don't need it.  There are two ways for threads
to terminate.  1)  Call apr_thread_exit.  2)  return from the function
that was started when the thread was created.  We happen to use option 2,
because it fits our model better.  Do not misinterpret a choice for a
flaw.  Even before the APR threading code was written, there was a hybrid
thread/process version of Apache.  Versions of this can be found in the
apache-apr repository.  That original hybrid Apache did not EVER call
pthread_exit().  This was a conscious choice made by myself, Bill
Stoddard, and Manoj Kasichainula.

> > Secondly, as long as the thread has access to the apr_thread_t, it also
> > has access to the pool within that value.
>
> Well, I disagree that the thread should have access to its underlying
> apr_thread_t.  It's a very awkward thing to do.  Doable?  Certainly.
> Clean?  No.  You now need a pointer into the thread array (or
> linked-list if that is how you do it - almost all places do it now with
> arrays) passed to the worker function.  Gag.

So it has been implemented poorly.  That doesn't mean anything.  A poor
implementation is very often where things begin.  It is relatively simple
to fix the implementation.

> And, once a thread is spawned, it is now on its own for memory.  So,
> it should create a SMS independent of any other SMS.  That's the goal
> and driving force behind SMS - we need a per-thread SMS.

SMS has nothing to do with threads.  I made a mistake when I wrote APR.  I
tied it to pools.  But pools don't work for all apps.  They happen to work
really well for the web server, but most apps don't have memory profiles
like a web server.  The idea of an SMS-like memory allocator was discussed
years ago, and the idea was to make APR useful outside of the web server.

> There is *zero* benefit to having any relationship between the
> thread's memory pool and the parent's memory pool.  You can't cleanup
> the thread from the parent anyway, so trust the thread to cleanup
> itself (as well as its pool and any memory allocations).  I fail to
> see the problem here.  Sever the imagined relationship.  The code
> becomes simpler, too.  -- justin

Pools are by their very nature hierarchical.  That is why the relationship
is there, and why it needs to remain there.  You can't just rely on the
thread to cleanup itself.  Pools (and SMS's) are used for a LOT more than
just memory allocation in the server.  They make sure that descriptors are
closed correctly.  In some places, they are used to make sure that
anything the child opened that isn't returned to the OS automatically is
returned when the child goes away.

If you divorce the thread pool from the pool for the child, you WILL break
many assumptions in the server.

Ryan

_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------



Re: Pools in threads WAS Re: Terminating threads in a process, WAS: RE: [PATCH] Problems with MPM threaded

Posted by Justin Erenkrantz <je...@ebuilt.com>.
On Sun, Jul 15, 2001 at 02:33:54PM -0700, rbb@covalent.net wrote:
> Guys, before you make comments like this, you should really read the code.
> First of all, the thread_exit call needs to take in the thread variable.
> Without it, platforms like OS/2 can't return values from the thread exit
> routine.

We could stipulate in APR that on OS/2 we won't return the result 
code.  Big deal.  It's not the end of the world.  And, it's only a hack
that works in conjunction with OS/2's apr_thread_join.  OS/2 threads
obviously don't support return codes.  APR is only as good as the
underlying thread library.

BeOS, Unix (pthread), and Win32 don't need the thread structure to 
destroy the thread or return the result code.  That seems to be the 
consensus on how threads should operate.  

If you are willing to lose the return code on OS/2, you now have OS/2 
not needing the thread structure either.  APR is a game of tradeoffs - 
this is one we should make in order to get a better API at the cost of 
something that this native OS doesn't provide anyway.

We should be seeing red flags everywhere because our own code isn't
calling the apr_thread_exit() function.  Why?  The API is, uh, 
lacking.

> Secondly, as long as the thread has access to the apr_thread_t, it also
> has access to the pool within that value.

Well, I disagree that the thread should have access to its underlying
apr_thread_t.  It's a very awkward thing to do.  Doable?  Certainly.
Clean?  No.  You now need a pointer into the thread array (or
linked-list if that is how you do it - almost all places do it now with
arrays) passed to the worker function.  Gag.

And, once a thread is spawned, it is now on its own for memory.  So, 
it should create a SMS independent of any other SMS.  That's the goal 
and driving force behind SMS - we need a per-thread SMS.

There is *zero* benefit to having any relationship between the 
thread's memory pool and the parent's memory pool.  You can't cleanup 
the thread from the parent anyway, so trust the thread to cleanup 
itself (as well as its pool and any memory allocations).  I fail to 
see the problem here.  Sever the imagined relationship.  The code 
becomes simpler, too.  -- justin


RE: Pools in threads

Posted by Sander Striker <st...@apache.org>.
>>> Fair enough. It's just that in order to opt-out of the 
>>> child-pool creating
>>> process in apr_thread_create, we're going to have to add a parameter
>> 
>> Why are we so desperate in opting out the child-pool creation?
>> I don't really have problems with a child pool for each thread. 
>> Actually, it will make the dynamic locking a lot easier to implement
>> if it stays.
> 
> The problem is that apr_thread_create is completely bogus right now.
>
> The child thread has no access to that pool in apr_thread_t->pool.
> If you want a pool in the thread, you should be creating inside
> of the thread's function not in apr_thread_create.

I can live with that. It's the registration of the thread with
the parent sms [when/if pools==sms] that has my interest :)
 
> And, apr_thread_exit call should *not* be taking in an apr_thread_t
> because the child doesn't have access to that either.  

Can't we pass in a data structure to the thread function which has
all the required information? The data the user wants to pass in will
need to be in the data structure aswell ofcourse.

> We're enforcing the use of global variables to work around this and 
> that's plain wrong.  -- justin

Yes, I agree.

Sander

Re: Pools in threads WAS Re: Terminating threads in a process, WAS: RE: [PATCH] Problems with MPM threaded

Posted by rb...@covalent.net.
On Sun, 15 Jul 2001, Justin Erenkrantz wrote:

> On Sun, Jul 15, 2001 at 07:16:35PM +0200, Sander Striker wrote:
> > > Fair enough. It's just that in order to opt-out of the child-pool creating
> > > process in apr_thread_create, we're going to have to add a parameter
> >
> > Why are we so desperate in opting out the child-pool creation?
> > I don't really have problems with a child pool for each thread. Actually,
> > it will make the dynamic locking a lot easier to implement if it stays.
>
> The problem is that apr_thread_create is completely bogus right now.
>
> The child thread has no access to that pool in apr_thread_t->pool.
> If you want a pool in the thread, you should be creating inside
> of the thread's function not in apr_thread_create.
>
> And, apr_thread_exit call should *not* be taking in an apr_thread_t
> because the child doesn't have access to that either.
>
> We're enforcing the use of global variables to work around this and
> that's plain wrong.  -- justin

Guys, before you make comments like this, you should really read the code.
First of all, the thread_exit call needs to take in the thread variable.
Without it, platforms like OS/2 can't return values from the thread exit
routine.

Secondly, as long as the thread has access to the apr_thread_t, it also
has access to the pool within that value.

What you all need to realize, is that some of the annoying pieces of APR
exist because we tried to do it the way that makes sense to all of you,
and we had to change it to make it work on all platforms.  Please, look
through what ALL platforms do before you decide to go changing API's.  You
are going to break things that work today.

Ryan

_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------