apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sander Striker" <stri...@samba-tng.org>
Subject RE: APR shared memory requirements.
Date Thu, 10 May 2001 15:05:40 GMT
Ok, trying to shed some light on this, because I'm afraid people
are going to get confused.

>>> the idea of providing an independent apr_memsys_join() with
>>> totally separate memory, totally separate semantics, that can
>>> cope with totally alien apr_memsys instances, thereby
>>> guaranteeing you destruction ordering / dependencies, seems
>>> like something that you clearly perceive there is a need for,
>>> that also keeps me happy.
>>>
>>> the same principle applies to apr_pool_join() (see other message).
>>
>> Why not simply register a cleanup of one memsys for it's (newborn)
>> child?
>
> urr... *thinks*...
>
> in what way?
>
> i mean, you can register a cleanup with memory associated
> with memory allocated _from_ a memsys.
>
> what we intended to do was to implement apr_pool to use an
> apr_memsys instance instead of hard-coding malloc/free in it.
>
> at that time, you can associate a memsys cleanup,
> in the apr_pool_initialise(), that calls apr_pool_destroy(),
> which will call pool destruction
> on all memory in the pool, and once _that's_ done, the memsys
> will free the memory fragments used by that pool.
>
> so, if you decide to destroy a memsys instance, and there
> _happen_ to be some pools created from it (independent
> or otherwise), they will all have apr_pool_destroy()
> called on them, and everybody's happy.
>
> .... right? [please say yes, please say yes, please tell
> me you don't want apr_memsys_join() guarantees :) ]
>
> so, when you say child, well... there aren't any?
>
> either that, or i am misunderstanding what you mean by
> child.
>
>
> > I would _hope_ we are implementing cleanups in all memory
> > models, since this is absolutely an essential feature.
>
> that's up to the implementors (developers) of each memsys model :)
> essential as it may be :)
>
> > One aspect of shmem/mmap cleanups, well, we actually have two different
> > types of cleanups.  One is the 'destructor', the other a 'detach'.
>
> could you possibly explain that further.
>
> currently, we have reset and destroy.  reset just trashes everything
> but 'resets' it back to as if you had just created the memsys instance.
>
> destroy does the same but then is responsible for destroying itself
> as well.

Actually, I don't think this is what Bill (how do you get from William
A. Rowe, Jr. to Bill??) meant.

We only support one type of cleanup function in the framework at the moment.
The cleanup functions are associated with a memory system instance
and called on _two_ occassions:
 - whenever apr_memory_system_reset() is called on the memory system;
 - whenever apr_memory_system_destroy() is called on the memory system.

So effectively apr_memory_system_reset() puts the memory system in the
state it was right after creation. It is therefor important _not_ to
register cleanup functions in the create when you implement a reset.
This implies that it is not wise to do so for any tracking memory
system (a catagory pools are definitely in).

If you really need two different types of cleanup functions there
are three options:
 - associate a type with the cleanup function;
 - implement a second registration function, etc. (this is what is done
   in the pools code, personally, if needed I like option one better);
 - Only implement it for a specific memory system.

For the record, a memory system instance that is the child of another
is _not_ guaranteed to have its reset or destroy function called. Since
these two functions are only allowed to do memory freeing, including
the memory system itself, they can be skipped by the parent if it is
tracking. [Hmmm, I might again have people lost now :-) ]

>> Of course, if multiple, disparate apps share the same shmem/mmap
cleanups,
>> it's up to them to agree on the destructor semantic.  No promises that
>> the 'last one out the door, turn out the lights' knows which
>> light switch to turn out :-)
>
> :)
>
> which is why i am nervous about apr_pool_join() and apr_memsys_join().
>
> but then again, it might be that i am nervous about the
> implications of _not_ having those functions, i haven't quite
> worked out which!

It is entirely up to the implementation of the memory system to take
care of this. In case of a shared memory system reference counting
would be the way to go (the refcount decrease should be done in
the pre_destroy). When the refcount hits zero you do the cleanups...
Argh, ok, this cannot be done with the code as such, I'll see what
can be done about this...
Thinking about this it is probably not wise to allow shared memory
systems to have a parent...

Ok, lets see the current order of events that take place when
destroy is called:

 - all the cleanup functions of the children are called (this is
    recursive, so the relative with the greatest distance has its
    cleanups called first)
 - right after the cleanup functions the pre_destroy functions of
   the children are called
 - all cleanup functions of the memory system itself are called
 - the pre_destroy function of the memory system itself is called
 - the destroy function of the memory system itself is called *)

*) This last step could be a number of things, but this is just
   for clarification. When there is no destroy, the parents free
   function is used.

Lets see the current order of events that take place when
reset is called *):

 - all the cleanup functions of the children are called (this is
    recursive, so the relative with the greatest distance has its
    cleanups called first)
 - right after the cleanup functions the pre_destroy functions of
   the children are called
 - all cleanup functions of the memory system itself are called
 - the reset function of the memory system itself is called

*) This will only work on tracking memory systems, it is no point
   (and there are no means) to reset a non tracking memory system;
   this will only result in memory leaks.

Looking at this we might want to call and register cleanups of a
certain types: CLEANUP_ON_RESET, CLEANUP_ON_DESTROY, CLEANUP_ALWAYS.
This would render pre_destroy obsolete :-)

Oh, before I forget, the cleanups are 'last in - first called'.

Hope this helps a bit (it certainly did me), if you guys are interested
in typed cleanups I'm willing to provide a patch this weekend,

Sander


Mime
View raw message