summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/timer.c
diff options
context:
space:
mode:
authorPoornima G <pgurusid@redhat.com>2015-02-19 05:29:02 +0530
committerVijay Bellur <vbellur@redhat.com>2015-03-02 20:31:56 -0800
commit7e416b6d00d626219c8d2067be720a915c4f85b1 (patch)
tree928f60594cf9af5a8b6d5bd71289232d27918474 /libglusterfs/src/timer.c
parent84e6eac265c87be5e436f3e7a41f40dc2d9c65c5 (diff)
libglusterfs: Add timer thread destroy code.
Change-Id: Iafbbbfd9319751742b3c79419e1dd8e2958fee07 BUG: 1093594 Signed-off-by: Poornima G <pgurusid@redhat.com> Reviewed-on: http://review.gluster.org/9701 Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs/src/timer.c')
-rw-r--r--libglusterfs/src/timer.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
index a059cc2122f..928b3681c89 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -36,6 +36,15 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,
return NULL;
}
+ /* ctx and its fields are not accessed inside mutex!?
+ * TODO: Even with this there is a possiblity of race
+ * when cleanup_started is set after checking for it
+ */
+ if (ctx->cleanup_started) {
+ gf_log_callingfn ("timer", GF_LOG_INFO, "ctx cleanup started");
+ return NULL;
+ }
+
reg = gf_timer_registry_init (ctx);
if (!reg) {
@@ -120,11 +129,18 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,
return 0;
}
+static inline void __delete_entry (gf_timer_t *event) {
+ event->next->prev = event->prev;
+ event->prev->next = event->next;
+ GF_FREE (event);
+}
+
void *
gf_timer_proc (void *ctx)
{
gf_timer_registry_t *reg = NULL;
const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
+ gf_timer_t *event = NULL;
if (ctx == NULL)
{
@@ -141,7 +157,6 @@ gf_timer_proc (void *ctx)
while (!reg->fin) {
uint64_t now;
struct timespec now_ts;
- gf_timer_t *event = NULL;
timespec_now (&now_ts);
now = TS (now_ts);
@@ -172,12 +187,19 @@ gf_timer_proc (void *ctx)
pthread_mutex_lock (&reg->lock);
{
+ /* Do not call gf_timer_call_cancel(),
+ * it will lead to deadlock
+ */
while (reg->active.next != &reg->active) {
- gf_timer_call_cancel (ctx, reg->active.next);
+ event = reg->active.next;
+ /* cannot call list_del as the event doesnt have
+ * list_head*/
+ __delete_entry (event);
}
while (reg->stale.next != &reg->stale) {
- gf_timer_call_cancel (ctx, reg->stale.next);
+ event = reg->stale.next;
+ __delete_entry (event);
}
}
pthread_mutex_unlock (&reg->lock);
@@ -215,3 +237,18 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx)
out:
return ctx->timer;
}
+
+void
+gf_timer_registry_destroy (glusterfs_ctx_t *ctx)
+{
+ pthread_t thr_id;
+ gf_timer_registry_t *reg = NULL;
+
+ if (ctx == NULL)
+ return;
+
+ reg = ctx->timer;
+ thr_id = reg->th;
+ reg->fin = 1;
+ pthread_join (thr_id, NULL);
+}