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?

Reply via email to