|
|
cb8e9e |
From 9b237463a8f5c75cff66364d07278217f8e4e586 Mon Sep 17 00:00:00 2001
|
|
|
cb8e9e |
From: Anand Avati <avati@redhat.com>
|
|
|
cb8e9e |
Date: Fri, 6 Dec 2013 17:31:57 -0800
|
|
|
cb8e9e |
Subject: [PATCH 243/244] timer: fix race between gf_timer_call_cancel() and gf_timer_proc()
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Backport of http://review.gluster.org/6459
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Change-Id: Ie264d3d591352e4a8ddaa90ae2174d9c552396f1
|
|
|
cb8e9e |
BUG: 1242423
|
|
|
cb8e9e |
Signed-off-by: Anand Avati <avati@redhat.com>
|
|
|
cb8e9e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/53060
|
|
|
cb8e9e |
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
cb8e9e |
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
cb8e9e |
---
|
|
|
cb8e9e |
libglusterfs/src/timer.c | 53 ++++++++++++++-------------------------------
|
|
|
cb8e9e |
libglusterfs/src/timer.h | 2 +-
|
|
|
cb8e9e |
2 files changed, 18 insertions(+), 37 deletions(-)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
|
|
|
cb8e9e |
index 8344c9b..a4d1890 100644
|
|
|
cb8e9e |
--- a/libglusterfs/src/timer.c
|
|
|
cb8e9e |
+++ b/libglusterfs/src/timer.c
|
|
|
cb8e9e |
@@ -85,31 +85,11 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
int32_t
|
|
|
cb8e9e |
-gf_timer_call_stale (gf_timer_registry_t *reg,
|
|
|
cb8e9e |
- gf_timer_t *event)
|
|
|
cb8e9e |
-{
|
|
|
cb8e9e |
- if (reg == NULL || event == NULL)
|
|
|
cb8e9e |
- {
|
|
|
cb8e9e |
- gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL,
|
|
|
cb8e9e |
- LG_MSG_INVALID_ARG, "invalid argument");
|
|
|
cb8e9e |
- return 0;
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- event->next->prev = event->prev;
|
|
|
cb8e9e |
- event->prev->next = event->next;
|
|
|
cb8e9e |
- event->next = ®->stale;
|
|
|
cb8e9e |
- event->prev = event->next->prev;
|
|
|
cb8e9e |
- event->next->prev = event;
|
|
|
cb8e9e |
- event->prev->next = event;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- return 0;
|
|
|
cb8e9e |
-}
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
-int32_t
|
|
|
cb8e9e |
gf_timer_call_cancel (glusterfs_ctx_t *ctx,
|
|
|
cb8e9e |
gf_timer_t *event)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
gf_timer_registry_t *reg = NULL;
|
|
|
cb8e9e |
+ gf_boolean_t fired = _gf_false;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
if (ctx == NULL || event == NULL)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
@@ -128,13 +108,21 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,
|
|
|
cb8e9e |
|
|
|
cb8e9e |
pthread_mutex_lock (®->lock);
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
+ fired = event->fired;
|
|
|
cb8e9e |
+ if (fired)
|
|
|
cb8e9e |
+ goto unlock;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
event->next->prev = event->prev;
|
|
|
cb8e9e |
event->prev->next = event->next;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
+unlock:
|
|
|
cb8e9e |
pthread_mutex_unlock (®->lock);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- GF_FREE (event);
|
|
|
cb8e9e |
- return 0;
|
|
|
cb8e9e |
+ if (!fired) {
|
|
|
cb8e9e |
+ GF_FREE (event);
|
|
|
cb8e9e |
+ return 0;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ return -1;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
static inline void __delete_entry (gf_timer_t *event) {
|
|
|
cb8e9e |
@@ -181,7 +169,9 @@ gf_timer_proc (void *ctx)
|
|
|
cb8e9e |
at = TS (event->at);
|
|
|
cb8e9e |
if (event != ®->active && now >= at) {
|
|
|
cb8e9e |
need_cbk = 1;
|
|
|
cb8e9e |
- gf_timer_call_stale (reg, event);
|
|
|
cb8e9e |
+ event->next->prev = event->prev;
|
|
|
cb8e9e |
+ event->prev->next = event->next;
|
|
|
cb8e9e |
+ event->fired = 1;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
pthread_mutex_unlock (®->lock);
|
|
|
cb8e9e |
@@ -192,15 +182,13 @@ gf_timer_proc (void *ctx)
|
|
|
cb8e9e |
THIS = event->xl;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
event->callbk (event->data);
|
|
|
cb8e9e |
- /*This callbk above would have freed the event
|
|
|
cb8e9e |
- * by calling timer_cancel, don't ever touch it
|
|
|
cb8e9e |
- * again*/
|
|
|
cb8e9e |
+ GF_FREE (event);
|
|
|
cb8e9e |
if (old_THIS) {
|
|
|
cb8e9e |
THIS = old_THIS;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
- else
|
|
|
cb8e9e |
+ } else {
|
|
|
cb8e9e |
break;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
nanosleep (&sleepts, NULL);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
@@ -216,11 +204,6 @@ gf_timer_proc (void *ctx)
|
|
|
cb8e9e |
* list_head*/
|
|
|
cb8e9e |
__delete_entry (event);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- while (reg->stale.next != ®->stale) {
|
|
|
cb8e9e |
- event = reg->stale.next;
|
|
|
cb8e9e |
- __delete_entry (event);
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
pthread_mutex_unlock (®->lock);
|
|
|
cb8e9e |
pthread_mutex_destroy (®->lock);
|
|
|
cb8e9e |
@@ -249,8 +232,6 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx)
|
|
|
cb8e9e |
pthread_mutex_init (®->lock, NULL);
|
|
|
cb8e9e |
reg->active.next = ®->active;
|
|
|
cb8e9e |
reg->active.prev = ®->active;
|
|
|
cb8e9e |
- reg->stale.next = ®->stale;
|
|
|
cb8e9e |
- reg->stale.prev = ®->stale;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
ctx->timer = reg;
|
|
|
cb8e9e |
gf_thread_create (®->th, NULL, gf_timer_proc, ctx);
|
|
|
cb8e9e |
diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h
|
|
|
cb8e9e |
index e64b350..35d99be 100644
|
|
|
cb8e9e |
--- a/libglusterfs/src/timer.h
|
|
|
cb8e9e |
+++ b/libglusterfs/src/timer.h
|
|
|
cb8e9e |
@@ -29,12 +29,12 @@ struct _gf_timer {
|
|
|
cb8e9e |
gf_timer_cbk_t callbk;
|
|
|
cb8e9e |
void *data;
|
|
|
cb8e9e |
xlator_t *xl;
|
|
|
cb8e9e |
+ gf_boolean_t fired;
|
|
|
cb8e9e |
};
|
|
|
cb8e9e |
|
|
|
cb8e9e |
struct _gf_timer_registry {
|
|
|
cb8e9e |
pthread_t th;
|
|
|
cb8e9e |
char fin;
|
|
|
cb8e9e |
- struct _gf_timer stale;
|
|
|
cb8e9e |
struct _gf_timer active;
|
|
|
cb8e9e |
pthread_mutex_t lock;
|
|
|
cb8e9e |
};
|
|
|
cb8e9e |
--
|
|
|
cb8e9e |
1.7.1
|
|
|
cb8e9e |
|