summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhou Zhengping <johnzzpcrystal@gmail.com>2016-06-26 19:56:58 -0400
committerJeff Darcy <jdarcy@redhat.com>2016-07-09 06:50:31 -0700
commit693eccd456c4fc7dfadb72069da906544cf19733 (patch)
treeace3705b6ada28d89e770df6fce538061f48503d
parent9886d568a7a8839bf3acc81cb1111fa372ac5270 (diff)
libglusterfs: race condition when set ctx->timer in function gf_timer_registry_init
1.fix race conditon when set ctx->timer 2.use typical list_head operation instead of verbose list's operation 3.add file "tags" into .gitignore Signed-off-by: Zhou Zhengping <johnzzpcrystal@gmail.com> Change-Id: I4ec55e41356633cf1399536d202c58e19b309f00 BUG: 1350191 Reviewed-on: http://review.gluster.org/14800 Smoke: Gluster Build System <jenkins@build.gluster.org> Tested-by: Zhou Zhengping <johnzzpcrystal@gmail.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
-rw-r--r--.gitignore1
-rw-r--r--libglusterfs/src/timer.c77
-rw-r--r--libglusterfs/src/timer.h10
3 files changed, 39 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index e5c699beaf8..33f6e0905b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ build
config.*
configure
cscope.*
+tags
depcomp
INSTALL
install-sh
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
index bcdc5da5571..a24a07804a8 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -57,16 +57,11 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,
event->xl = THIS;
LOCK (&reg->lock);
{
- trav = reg->active.prev;
- while (trav != &reg->active) {
+ list_for_each_entry_reverse (trav, &reg->active, list) {
if (TS (trav->at) < at)
break;
- trav = trav->prev;
}
- event->prev = trav;
- event->next = event->prev->next;
- event->prev->next = event;
- event->next->prev = event;
+ list_add (&event->list, &trav->list);
}
UNLOCK (&reg->lock);
return event;
@@ -105,9 +100,7 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,
fired = event->fired;
if (fired)
goto unlock;
-
- event->next->prev = event->prev;
- event->prev->next = event->next;
+ list_del (&event->list);
}
unlock:
UNLOCK (&reg->lock);
@@ -120,20 +113,13 @@ unlock:
}
-static void
-__delete_entry (gf_timer_t *event) {
- event->next->prev = event->prev;
- event->prev->next = event->next;
- GF_FREE (event);
-}
-
-
static void *
gf_timer_proc (void *data)
{
gf_timer_registry_t *reg = data;
const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
gf_timer_t *event = NULL;
+ gf_timer_t *tmp = NULL;
xlator_t *old_THIS = NULL;
while (!reg->fin) {
@@ -148,13 +134,15 @@ gf_timer_proc (void *data)
LOCK (&reg->lock);
{
- event = reg->active.next;
- at = TS (event->at);
- if (event != &reg->active && now >= at) {
- need_cbk = 1;
- event->next->prev = event->prev;
- event->prev->next = event->next;
- event->fired = _gf_true;
+ list_for_each_entry_safe (event,
+ tmp, &reg->active, list) {
+ at = TS (event->at);
+ if (now >= at) {
+ need_cbk = 1;
+ event->fired = _gf_true;
+ list_del (&event->list);
+ break;
+ }
}
}
UNLOCK (&reg->lock);
@@ -181,11 +169,9 @@ gf_timer_proc (void *data)
/* Do not call gf_timer_call_cancel(),
* it will lead to deadlock
*/
- while (reg->active.next != &reg->active) {
- event = reg->active.next;
- /* cannot call list_del as the event doesnt have
- * list_head*/
- __delete_entry (event);
+ list_for_each_entry_safe (event, tmp, &reg->active, list) {
+ list_del (&event->list);
+ GF_FREE (event);
}
}
UNLOCK (&reg->lock);
@@ -216,26 +202,23 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx)
LOCK (&ctx->lock);
{
reg = ctx->timer;
- }
- UNLOCK (&ctx->lock);
- if (!reg) {
+ if (reg) {
+ UNLOCK (&ctx->lock);
+ goto out;
+ }
reg = GF_CALLOC (1, sizeof (*reg),
- gf_common_mt_gf_timer_registry_t);
- if (!reg)
- return NULL;
-
- LOCK_INIT (&reg->lock);
- reg->active.next = &reg->active;
- reg->active.prev = &reg->active;
-
- LOCK (&ctx->lock);
- {
- ctx->timer = reg;
+ gf_common_mt_gf_timer_registry_t);
+ if (!reg) {
+ UNLOCK (&ctx->lock);
+ goto out;
}
- UNLOCK (&ctx->lock);
- gf_thread_create (&reg->th, NULL, gf_timer_proc, reg);
+ ctx->timer = reg;
+ LOCK_INIT (&reg->lock);
+ INIT_LIST_HEAD (&reg->active);
}
-
+ UNLOCK (&ctx->lock);
+ gf_thread_create (&reg->th, NULL, gf_timer_proc, reg);
+out:
return reg;
}
diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h
index 0224b0897f9..32b246cf00d 100644
--- a/libglusterfs/src/timer.h
+++ b/libglusterfs/src/timer.h
@@ -19,7 +19,13 @@
typedef void (*gf_timer_cbk_t) (void *);
struct _gf_timer {
- struct _gf_timer *next, *prev;
+ union {
+ struct list_head list;
+ struct {
+ struct _gf_timer *next;
+ struct _gf_timer *prev;
+ };
+ };
struct timespec at;
gf_timer_cbk_t callbk;
void *data;
@@ -30,7 +36,7 @@ struct _gf_timer {
struct _gf_timer_registry {
pthread_t th;
char fin;
- struct _gf_timer active;
+ struct list_head active;
gf_lock_t lock;
};