apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mladen Turk <mt...@apache.org>
Subject Re: svn commit: r677505 - /apr/apr-util/trunk/misc/apr_reslist.c
Date Thu, 17 Jul 2008 11:59:09 GMT
Bojan Smojver wrote:
> Quoting "Mladen Turk" <mturk@apache.org>:
> 
>> So the pool P is not destroyed before its subpools, only
>> the callback is called before subpools are destroyed.
> 
> True, but that's not what I see as the problem.
> 
> Imagine R is a database connection and S a prepared statement that 
> depends on R (i.e. uses structures R points to during destruction). If R 
> is destroyed (i.e. pointer to it points nowhere after that), any attempt 
> to destroy S will give segfaults.
> 
> It is a reasonable APR application design to expect that if S registered 
> a cleanup with the sub-pool of the pool from which R was allocated, that 
> this cleanup will run OK. But, because R was already destroyed, this is 
> not true any more.
> 
> Can't you just use malloc()/free() in destructor for temporary memory 
> needs? Both should be localised to the destructor...
> 

OK. Seems this is somehow unclear.
What you are saying is not the case because R is not destroyed
neither points to the invalid address. The callback is called
and the destructor is executed.

The apr_reslist is special kind of object that has two major
things and those are constructor and destructor.

If constructor creates a subpool from the reslist pool
then this subpool will be destroyed before destructor is called.
So the destructor *must not* call apr_pool_destroy(subpool)
if the parent pool is inside apr_pool_destroy (tricky).
What this does is call destructor for each resource before any
subpool is destroyed. Now, the destructor must destroy anything
constructor created. If it was prepared statement, connection, ...

Without that it is impossible to have subpool destroy inside destructor
callback, because it will be called on zombie pool (already destroyed)

With your case if your destructor does nothing, there will be no
change at all.
If you application works when you explicitly close all R and then
call pool destroy it will with this. If not, well :)

Usually the application calls:
apr_reslist_create(pool)
... do something with reslist
apr_reslist_destroy
    reslist_destroy_callback
       for each r in resources call desctructor(r)

...
apr_pool_destroy(pool)
   destory all subpools

Now if somone hits CTRL+C then everything changes to:
apr_reslist_create(pool)
... do something with reslist
apr_pool_destroy(pool)
    destroy all subpools
    reslist_destroy_callback
       for each r in resources call desctructor(r)

So destructor needs an mechanism to figure out
how it was called and if it's OK to an operation
on the pool.


Regards
-- 
^(TM)

Mime
View raw message