diff options
Diffstat (limited to 'database/engine/rrdenglocking.c')
-rw-r--r-- | database/engine/rrdenglocking.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/database/engine/rrdenglocking.c b/database/engine/rrdenglocking.c index 0c1d26f25a..754d802a23 100644 --- a/database/engine/rrdenglocking.c +++ b/database/engine/rrdenglocking.c @@ -20,7 +20,12 @@ struct page_cache_descr *rrdeng_create_pg_cache_descr(struct rrdengine_instance void rrdeng_destroy_pg_cache_descr(struct rrdengine_instance *ctx, struct page_cache_descr *pg_cache_descr) { + /* Flush any lock and condition variable users */ + uv_mutex_lock(&pg_cache_descr->mutex); + uv_mutex_unlock(&pg_cache_descr->mutex); + uv_cond_destroy(&pg_cache_descr->cond); + uv_mutex_destroy(&pg_cache_descr->mutex); freez(pg_cache_descr); rrd_stat_atomic_add(&ctx->stats.page_cache_descriptors, -1); @@ -95,7 +100,7 @@ void rrdeng_page_descr_mutex_lock(struct rrdengine_instance *ctx, struct rrdeng_ void rrdeng_page_descr_mutex_unlock(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr) { unsigned long old_state, new_state, ret_state, old_users; - struct page_cache_descr *pg_cache_descr, *delete_pg_cache_descr = NULL; + struct page_cache_descr *pg_cache_descr; uint8_t we_locked; uv_mutex_unlock(&descr->pg_cache_descr->mutex); @@ -111,8 +116,7 @@ void rrdeng_page_descr_mutex_unlock(struct rrdengine_instance *ctx, struct rrden ret_state = ulong_compare_and_swap(&descr->pg_cache_descr_state, old_state, 0); if (old_state == ret_state) { /* success */ - rrdeng_destroy_pg_cache_descr(ctx, delete_pg_cache_descr); - return; + break; } continue; /* spin */ } @@ -124,15 +128,12 @@ void rrdeng_page_descr_mutex_unlock(struct rrdengine_instance *ctx, struct rrden pg_cache_descr = descr->pg_cache_descr; /* caller is the only page cache descriptor user and there are no pending references on the page */ if ((old_state & PG_CACHE_DESCR_DESTROY) && (1 == old_users) && - !pg_cache_descr->flags && !pg_cache_descr->refcnt) { - assert(!pg_cache_descr->waiters); - + !pg_cache_descr->flags && !pg_cache_descr->refcnt && !pg_cache_descr->waiters) { new_state = PG_CACHE_DESCR_LOCKED; ret_state = ulong_compare_and_swap(&descr->pg_cache_descr_state, old_state, new_state); if (old_state == ret_state) { we_locked = 1; - delete_pg_cache_descr = pg_cache_descr; - descr->pg_cache_descr = NULL; + rrdeng_destroy_pg_cache_descr(ctx, pg_cache_descr); /* retry */ continue; } @@ -149,6 +150,7 @@ void rrdeng_page_descr_mutex_unlock(struct rrdengine_instance *ctx, struct rrden } /* spin */ } + } /* @@ -159,11 +161,11 @@ void rrdeng_page_descr_mutex_unlock(struct rrdengine_instance *ctx, struct rrden void rrdeng_try_deallocate_pg_cache_descr(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr) { unsigned long old_state, new_state, ret_state, old_users; - struct page_cache_descr *pg_cache_descr = NULL; - uint8_t just_locked, can_free, must_unlock; + struct page_cache_descr *pg_cache_descr; + uint8_t just_locked, we_freed, must_unlock; just_locked = 0; - can_free = 0; + we_freed = 0; must_unlock = 0; while (1) { /* spin */ old_state = descr->pg_cache_descr_state; @@ -175,11 +177,9 @@ void rrdeng_try_deallocate_pg_cache_descr(struct rrdengine_instance *ctx, struct must_unlock = 1; just_locked = 0; /* Try deallocate if there are no pending references on the page */ - if (!pg_cache_descr->flags && !pg_cache_descr->refcnt) { - assert(!pg_cache_descr->waiters); - - descr->pg_cache_descr = NULL; - can_free = 1; + if (!pg_cache_descr->flags && !pg_cache_descr->refcnt && !pg_cache_descr->waiters) { + rrdeng_destroy_pg_cache_descr(ctx, pg_cache_descr); + we_freed = 1; /* success */ continue; } @@ -188,7 +188,7 @@ void rrdeng_try_deallocate_pg_cache_descr(struct rrdengine_instance *ctx, struct if (unlikely(must_unlock)) { assert(0 == old_users); - if (can_free) { + if (we_freed) { /* success */ new_state = 0; } else { @@ -198,8 +198,6 @@ void rrdeng_try_deallocate_pg_cache_descr(struct rrdengine_instance *ctx, struct ret_state = ulong_compare_and_swap(&descr->pg_cache_descr_state, old_state, new_state); if (old_state == ret_state) { /* unlocked */ - if (can_free) - rrdeng_destroy_pg_cache_descr(ctx, pg_cache_descr); return; } continue; /* spin */ |