On Wed, 18 Jul 2001, Sander Striker wrote:
> Wouldn't it be wiser to implement cleanup management as a
> seperate entity, instead of piggy backing it on allocators?
i'm not sure... 'cause the only thing i think which is missing is
something like this:
typedef struct {
int die_soon_please;
int ref_count;
apr_lock_t *lock;
} thread_cleanup_t;
die_soon_please is initialised to 0
ref_count to 2
lock is initialised and released
to create a thread that you want cleanup for you create one of these
thread_cleanup_ts (malloc'd). then you register a cleanup in
the "parent thread"'s pool, such as the following:
apr_status_t thread_cleanup(void *_tc)
{
thread_cleanup_t *tc = _tc;
apr_lock_acquire(tc->lock);
if (--tc->ref_count) {
/* thread is still around, tell it to die asap */
tc->die_soon_please = 1;
apr_lock_release(tc->lock);
}
else {
/* thread has already exited, it took care of
* cleaning up its pool on the way out
*/
apr_lock_destroy(tc->lock);
free(tc);
}
return 0;
}
and then when the "child" thread wants to exit, it should do:
apr_pool_destroy(my_root_pool);
apr_lock_acquire(tc->lock);
if (--tc->ref_count == 0) {
/* parent asked us to go away, so we get to free up the
* structure
*/
free(tc->lock);
}
else {
apr_lock_release(tc->lock);
}
and at any time the child cares to ask if the parent told it to die
it can just test tc->die_soon_please.
this basically just moves the mutexes from the common path to the less
common path of parent/child relationship.
-dean
p.s. maybe this example will help highlight why apr_lock_t is far too
generic and there should be a more lightweight thread only mutex that
doesn't require lots of extra memory allocation?
|