>>> [EMAIL PROTECTED] 09/15/04 12:41 PM >>>
>I'm still trying to learn the complete design though.  I see that
>memcache_cache_free() can return with OBJECT_CLEANUP_BIT set, and that
>decrement_refcount() will react to it and free the memory if it is registered as
>a cleanup.  Will decrement_refcount() always be registered?  Just wondering if
>there are any code paths where we might leak memory.
An element will either be created or opened, both cases are registering 
decrement_refcount() as the cleanup function to be called when the thread
is done.
To remove the 2 noted possible race situations, in addition to another possible
one in store_body(), we could add the following 2 recursive functions,
that have to be called under the protection of the lock (it is now for
all 3 cases of atomic_set32()):
 
static void memcache_clear_cleanup_bit(cache_object_t *obj)
{
    apr_uint32_t tmp_refcount = obj->refcount;
 
    if(tmp_refcount != apr_atomic_cas32(&obj->refcount,
                                        obj->refcount & ~OBJECT_CLEANUP_BIT,
                                        tmp_refcount)) {
        memcache_clear_cleanup_bit(obj);
    }
}
static void memcache_set_cleanup_bit(cache_object_t *obj)
{
    apr_uint32_t tmp_refcount = obj->refcount;
 
    if(tmp_refcount != apr_atomic_cas32(&obj->refcount,
                                        tmp_refcount | OBJECT_CLEANUP_BIT,
                                        tmp_refcount)) {
        memcache_set_cleanup_bit(obj);
    }
}
One only additional thing is if I could call the set_cleanup_bit() within
memcache_cache_free(), it would centralize all the bit setting into
the 2 previous functions.
Thanks for your time on that case.
JJ

Reply via email to