From 92952a767ffe126e1dfa548be003ce2b0461065e Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Sat, 18 Jul 2015 10:04:13 +0530 Subject: [PATCH 245/245] Revert "timer: fix race between gf_timer_call_cancel() and gf_timer_proc()" This reverts commit 9b237463a8f5c75cff66364d07278217f8e4e586. BUG: 1244187 Change-Id: Ibb6c04ab6167071e62c7a33e114b3dd5931825c8 Signed-off-by: Pranith Kumar K Reviewed-on: https://code.engineering.redhat.com/gerrit/53266 Reviewed-by: Krishnan Parthasarathi Reviewed-by: Kaushal Madappa --- libglusterfs/src/timer.c | 48 +++++++++++++++++++++++++++++++-------------- libglusterfs/src/timer.h | 2 +- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c index a4d1890..e103f05 100644 --- a/libglusterfs/src/timer.c +++ b/libglusterfs/src/timer.c @@ -85,11 +85,30 @@ gf_timer_call_after (glusterfs_ctx_t *ctx, } int32_t +gf_timer_call_stale (gf_timer_registry_t *reg, + gf_timer_t *event) +{ + if (reg == NULL || event == NULL) { + gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL, + LG_MSG_INVALID_ARG, "invalid argument"); + return 0; + } + + event->next->prev = event->prev; + event->prev->next = event->next; + event->next = ®->stale; + event->prev = event->next->prev; + event->next->prev = event; + event->prev->next = event; + + return 0; +} + +int32_t gf_timer_call_cancel (glusterfs_ctx_t *ctx, gf_timer_t *event) { gf_timer_registry_t *reg = NULL; - gf_boolean_t fired = _gf_false; if (ctx == NULL || event == NULL) { @@ -108,21 +127,13 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx, pthread_mutex_lock (®->lock); { - fired = event->fired; - if (fired) - goto unlock; - event->next->prev = event->prev; event->prev->next = event->next; } -unlock: pthread_mutex_unlock (®->lock); - if (!fired) { - GF_FREE (event); - return 0; - } - return -1; + GF_FREE (event); + return 0; } static inline void __delete_entry (gf_timer_t *event) { @@ -169,9 +180,7 @@ gf_timer_proc (void *ctx) at = TS (event->at); if (event != ®->active && now >= at) { need_cbk = 1; - event->next->prev = event->prev; - event->prev->next = event->next; - event->fired = 1; + gf_timer_call_stale (reg, event); } } pthread_mutex_unlock (®->lock); @@ -182,7 +191,9 @@ gf_timer_proc (void *ctx) THIS = event->xl; } event->callbk (event->data); - GF_FREE (event); + /*This callbk above would have freed the event + * by calling timer_cancel, don't ever touch it + * again*/ if (old_THIS) { THIS = old_THIS; } @@ -204,6 +215,11 @@ gf_timer_proc (void *ctx) * list_head*/ __delete_entry (event); } + + while (reg->stale.next != ®->stale) { + event = reg->stale.next; + __delete_entry (event); + } } pthread_mutex_unlock (®->lock); pthread_mutex_destroy (®->lock); @@ -232,6 +248,8 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx) pthread_mutex_init (®->lock, NULL); reg->active.next = ®->active; reg->active.prev = ®->active; + reg->stale.next = ®->stale; + reg->stale.prev = ®->stale; ctx->timer = reg; gf_thread_create (®->th, NULL, gf_timer_proc, ctx); diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h index 35d99be..e64b350 100644 --- a/libglusterfs/src/timer.h +++ b/libglusterfs/src/timer.h @@ -29,12 +29,12 @@ struct _gf_timer { gf_timer_cbk_t callbk; void *data; xlator_t *xl; - gf_boolean_t fired; }; struct _gf_timer_registry { pthread_t th; char fin; + struct _gf_timer stale; struct _gf_timer active; pthread_mutex_t lock; }; -- 1.7.1