diff options
| author | Zhou Zhengping <johnzzpcrystal@gmail.com> | 2016-06-26 19:56:58 -0400 | 
|---|---|---|
| committer | Jeff Darcy <jdarcy@redhat.com> | 2016-07-09 06:50:31 -0700 | 
| commit | 693eccd456c4fc7dfadb72069da906544cf19733 (patch) | |
| tree | ace3705b6ada28d89e770df6fce538061f48503d /libglusterfs/src/timer.c | |
| parent | 9886d568a7a8839bf3acc81cb1111fa372ac5270 (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>
Diffstat (limited to 'libglusterfs/src/timer.c')
| -rw-r--r-- | libglusterfs/src/timer.c | 77 | 
1 files changed, 30 insertions, 47 deletions
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 (®->lock);          { -                trav = reg->active.prev; -                while (trav != ®->active) { +                list_for_each_entry_reverse (trav, ®->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 (®->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 (®->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 (®->lock);                          { -                                event = reg->active.next; -                                at = TS (event->at); -                                if (event != ®->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, ®->active, list) { +                                        at = TS (event->at); +                                        if (now >= at) { +                                                need_cbk = 1; +                                                event->fired = _gf_true; +                                                list_del (&event->list); +                                                break; +                                        }                                  }                          }                          UNLOCK (®->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 != ®->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, ®->active, list) { +                        list_del (&event->list); +                        GF_FREE (event);                  }          }          UNLOCK (®->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 (®->lock); -                reg->active.next = ®->active; -                reg->active.prev = ®->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 (®->th, NULL, gf_timer_proc, reg); +                ctx->timer = reg; +                LOCK_INIT (®->lock); +                INIT_LIST_HEAD (®->active);          } - +        UNLOCK (&ctx->lock); +        gf_thread_create (®->th, NULL, gf_timer_proc, reg); +out:          return reg;  }  | 
