From 92952a767ffe126e1dfa548be003ce2b0461065e Mon Sep 17 00:00:00 2001
From: Pranith Kumar K <pkarampu@redhat.com>
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 <pkarampu@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/53266
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Reviewed-by: Kaushal Madappa <kaushal@redhat.com>
---
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