diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/ctx.c | 3 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/timer.c | 128 | ||||
| -rw-r--r-- | libglusterfs/src/timer.h | 10 | 
4 files changed, 77 insertions, 67 deletions
diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c index c70d97bc5d4..2aa14654b9e 100644 --- a/libglusterfs/src/ctx.c +++ b/libglusterfs/src/ctx.c @@ -35,7 +35,8 @@ glusterfs_ctx_new ()  	ctx->daemon_pipe[0] = -1;  	ctx->daemon_pipe[1] = -1; -	ret = pthread_mutex_init (&ctx->lock, NULL); +        /* lock is never destroyed! */ +	ret = LOCK_INIT (&ctx->lock);  	if (ret) {  		free (ctx);  		ctx = NULL; diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 46131e11a3f..128dcd32e5f 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -32,6 +32,7 @@  #include "glusterfs-fops.h" /* generated XDR values for FOPs */  #include "list.h" +#include "locking.h"  #include "logging.h"  #include "lkowner.h"  #include "compat-uuid.h" @@ -430,7 +431,7 @@ struct _glusterfs_ctx {          void               *event_pool;          void               *iobuf_pool;          void               *logbuf_pool; -        pthread_mutex_t     lock; +        gf_lock_t           lock;          size_t              page_size;          struct list_head    graphs; /* double linked list of graphs - one per volfile parse */          glusterfs_graph_t  *active; /* the latest graph in use */ diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c index a072985acce..bcdc5da5571 100644 --- a/libglusterfs/src/timer.c +++ b/libglusterfs/src/timer.c @@ -15,6 +15,10 @@  #include "timespec.h"  #include "libglusterfs-messages.h" +/* fwd decl */ +static gf_timer_registry_t * +gf_timer_registry_init (glusterfs_ctx_t *); +  gf_timer_t *  gf_timer_call_after (glusterfs_ctx_t *ctx,                       struct timespec delta, @@ -33,17 +37,6 @@ 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_msg_callingfn ("timer", GF_LOG_INFO, 0, -                                  LG_MSG_CTX_CLEANUP_STARTED, "ctx cleanup " -                                  "started"); -                return NULL; -        } -          reg = gf_timer_registry_init (ctx);          if (!reg) { @@ -62,7 +55,7 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,          event->callbk = callbk;          event->data = data;          event->xl = THIS; -        pthread_mutex_lock (®->lock); +        LOCK (®->lock);          {                  trav = reg->active.prev;                  while (trav != ®->active) { @@ -75,10 +68,11 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,                  event->prev->next = event;                  event->next->prev = event;          } -        pthread_mutex_unlock (®->lock); +        UNLOCK (®->lock);          return event;  } +  int32_t  gf_timer_call_cancel (glusterfs_ctx_t *ctx,                        gf_timer_t *event) @@ -93,7 +87,12 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,                  return 0;          } -        reg = gf_timer_registry_init (ctx); +        LOCK (&ctx->lock); +        { +                reg = ctx->timer; +        } +        UNLOCK (&ctx->lock); +          if (!reg) {                  gf_msg ("timer", GF_LOG_ERROR, 0, LG_MSG_INIT_TIMER_FAILED,                          "!reg"); @@ -101,53 +100,42 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,                  return 0;          } -        pthread_mutex_lock (®->lock); +        LOCK (®->lock);          { -		fired = event->fired; -		if (fired) -			goto unlock; +                fired = event->fired; +                if (fired) +                        goto unlock;                  event->next->prev = event->prev;                  event->prev->next = event->next;          }  unlock: -        pthread_mutex_unlock (®->lock); +        UNLOCK (®->lock); -	if (!fired) { -		GF_FREE (event); -		return 0; +        if (!fired) { +                GF_FREE (event); +                return 0;          }          return -1;  } -static void __delete_entry (gf_timer_t *event) { + +static 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) + +static void * +gf_timer_proc (void *data)  { -        gf_timer_registry_t *reg = NULL; +        gf_timer_registry_t *reg = data;          const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };          gf_timer_t *event = NULL;          xlator_t   *old_THIS = NULL; -        if (ctx == NULL) -        { -                gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL, -                                  LG_MSG_INVALID_ARG, "invalid argument"); -                return NULL; -        } - -        reg = gf_timer_registry_init (ctx); -        if (!reg) { -                gf_msg ("timer", GF_LOG_ERROR, 0, LG_MSG_INIT_TIMER_FAILED, -                        "!reg"); -                return NULL; -        } -          while (!reg->fin) {                  uint64_t now;                  struct timespec now_ts; @@ -158,7 +146,7 @@ gf_timer_proc (void *ctx)                          uint64_t at;                          char need_cbk = 0; -                        pthread_mutex_lock (®->lock); +                        LOCK (®->lock);                          {                                  event = reg->active.next;                                  at = TS (event->at); @@ -169,7 +157,7 @@ gf_timer_proc (void *ctx)                                          event->fired = _gf_true;                                  }                          } -                        pthread_mutex_unlock (®->lock); +                        UNLOCK (®->lock);                          if (need_cbk) {                                  old_THIS = NULL;                                  if (event->xl) { @@ -188,7 +176,7 @@ gf_timer_proc (void *ctx)                  nanosleep (&sleepts, NULL);          } -        pthread_mutex_lock (®->lock); +        LOCK (®->lock);          {                  /* Do not call gf_timer_call_cancel(),                   * it will lead to deadlock @@ -200,42 +188,58 @@ gf_timer_proc (void *ctx)                          __delete_entry (event);                  }          } -        pthread_mutex_unlock (®->lock); -        pthread_mutex_destroy (®->lock); -        GF_FREE (((glusterfs_ctx_t *)ctx)->timer); +        UNLOCK (®->lock); +        LOCK_DESTROY (®->lock);          return NULL;  } -gf_timer_registry_t * + +static gf_timer_registry_t *  gf_timer_registry_init (glusterfs_ctx_t *ctx)  { +        gf_timer_registry_t *reg = NULL; +          if (ctx == NULL) {                  gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL,                                    LG_MSG_INVALID_ARG, "invalid argument");                  return NULL;          } -        if (!ctx->timer) { -                gf_timer_registry_t *reg = NULL; +        if (ctx->cleanup_started) { +                gf_msg_callingfn ("timer", GF_LOG_INFO, 0, +                                  LG_MSG_CTX_CLEANUP_STARTED, +                                  "ctx cleanup started"); +                return NULL; +        } +        LOCK (&ctx->lock); +        { +                reg = ctx->timer; +        } +        UNLOCK (&ctx->lock); +        if (!reg) {                  reg = GF_CALLOC (1, sizeof (*reg),                                   gf_common_mt_gf_timer_registry_t);                  if (!reg) -                        goto out; +                        return NULL; -                pthread_mutex_init (®->lock, NULL); +                LOCK_INIT (®->lock);                  reg->active.next = ®->active;                  reg->active.prev = ®->active; -                ctx->timer = reg; -                gf_thread_create (®->th, NULL, gf_timer_proc, ctx); - +                LOCK (&ctx->lock); +                { +                        ctx->timer = reg; +                } +                UNLOCK (&ctx->lock); +                gf_thread_create (®->th, NULL, gf_timer_proc, reg);          } -out: -        return ctx->timer; + +        return reg;  } +  void  gf_timer_registry_destroy (glusterfs_ctx_t *ctx)  { @@ -245,8 +249,18 @@ gf_timer_registry_destroy (glusterfs_ctx_t *ctx)          if (ctx == NULL)                  return; -        reg = ctx->timer; +        LOCK (&ctx->lock); +        { +                reg = ctx->timer; +                ctx->timer = NULL; +        } +        UNLOCK (&ctx->lock); + +        if (!reg) +                return; +          thr_id = reg->th;          reg->fin = 1;          pthread_join (thr_id, NULL); +        GF_FREE (reg);  } diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h index fff902814ed..0224b0897f9 100644 --- a/libglusterfs/src/timer.h +++ b/libglusterfs/src/timer.h @@ -20,7 +20,7 @@ typedef void (*gf_timer_cbk_t) (void *);  struct _gf_timer {          struct _gf_timer *next, *prev; -        struct timespec    at; +        struct timespec   at;          gf_timer_cbk_t    callbk;          void             *data;          xlator_t         *xl; @@ -31,7 +31,7 @@ struct _gf_timer_registry {          pthread_t        th;          char             fin;          struct _gf_timer active; -        pthread_mutex_t  lock; +        gf_lock_t        lock;  };  typedef struct _gf_timer gf_timer_t; @@ -47,12 +47,6 @@ int32_t  gf_timer_call_cancel (glusterfs_ctx_t *ctx,                        gf_timer_t *event); -void * -gf_timer_proc (void *data); - -gf_timer_registry_t * -gf_timer_registry_init (glusterfs_ctx_t *ctx); -  void  gf_timer_registry_destroy (glusterfs_ctx_t *ctx);  #endif /* _TIMER_H */  | 
