diff options
-rw-r--r-- | api/src/glfs-internal.h | 50 | ||||
-rw-r--r-- | api/src/glfs.c | 123 |
2 files changed, 100 insertions, 73 deletions
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 384050be8ad..71c83755ec3 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -21,6 +21,55 @@ #define DEFAULT_REVAL_COUNT 1 +/* + * According to pthread mutex and conditional variable ( cond, child_down_count, + * upcall mutex and mutex) initialization of struct glfs members, + * below GLFS_INIT_* flags are set in 'pthread_flags' member of struct glfs. + * The flags are set from glfs_init() and glfs_new_from_ctx() functions + * as part of fs inititialization. + * + * These flag bits are validated in glfs_fini() to destroy all or partially + * initialized mutex and conditional variables of glfs object. + * If you introduce new pthread mutex or conditional variable in glfs object, + * please make sure you have a flag bit intorduced here for proper cleanup + * in glfs_fini(). + * + */ + +#define PTHREAD_MUTEX_INIT(mutex, attr, flags, mask, label) do { \ + int __ret = -1; \ + __ret = pthread_mutex_init (mutex, attr); \ + if (__ret == 0) \ + flags |= mask; \ + else \ + goto label; \ +} while (0) + +#define PTHREAD_MUTEX_DESTROY(mutex, flags, mask) do { \ + if (flags & mask) \ + (void) pthread_mutex_destroy (mutex); \ +} while (0) + +#define PTHREAD_COND_INIT(cond, attr, flags, mask, label) do { \ + int __ret = -1; \ + __ret = pthread_cond_init (cond, attr); \ + if (__ret == 0) \ + flags |= mask; \ + else \ + goto label; \ +} while (0) + +#define PTHREAD_COND_DESTROY(cond, flags, mask) do { \ + if (flags & mask) \ + (void) pthread_cond_destroy (cond); \ +} while (0) + +#define GLFS_INIT_MUTEX 0x00000001 /* pthread_mutex_flag */ +#define GLFS_INIT_COND 0x00000002 /* pthread_cond_flag */ +#define GLFS_INIT_COND_CHILD 0x00000004 /* pthread_cond_child_down_flag */ +#define GLFS_INIT_MUTEX_UPCALL 0x00000008 /* pthread_mutex_upcall_flag */ + + #ifndef GF_DARWIN_HOST_OS #ifndef GFAPI_PUBLIC #define GFAPI_PUBLIC(sym, ver) /**/ @@ -154,6 +203,7 @@ struct glfs { pthread_mutex_t upcall_list_mutex; /* mutex for upcall entry list */ uint32_t pin_refcnt; + uint32_t pthread_flags; /* GLFS_INIT_* # defines set this flag */ }; struct glfs_fd { diff --git a/api/src/glfs.c b/api/src/glfs.c index 897d3eab809..5653f4d46c0 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -581,12 +581,42 @@ glfs_poller (void *data) return NULL; } -/* - * please note all the variable initializations done here probably - * need to be added in 'glfs_new_from_ctx()' as well, so that, - * we do not miss out while adding new members in 'fs'. -*/ +static struct glfs * +glfs_new_fs (const char *volname) +{ + struct glfs *fs = NULL; + + fs = CALLOC (1, sizeof (*fs)); + if (!fs) + return NULL; + + INIT_LIST_HEAD (&fs->openfds); + INIT_LIST_HEAD (&fs->upcall_list); + + PTHREAD_MUTEX_INIT (&fs->mutex, NULL, fs->pthread_flags, + GLFS_INIT_MUTEX, err); + + PTHREAD_COND_INIT (&fs->cond, NULL, fs->pthread_flags, + GLFS_INIT_COND, err); + + PTHREAD_COND_INIT (&fs->child_down_cond, NULL, fs->pthread_flags, + GLFS_INIT_COND_CHILD, err); + + PTHREAD_MUTEX_INIT (&fs->upcall_list_mutex, NULL, fs->pthread_flags, + GLFS_INIT_MUTEX_UPCALL, err); + + fs->volname = strdup (volname); + if (!fs->volname) + goto err; + + fs->pin_refcnt = 0; + return fs; + +err: + glfs_free_from_ctx (fs); + return NULL; +} struct glfs * pub_glfs_new (const char *volname) @@ -601,26 +631,10 @@ pub_glfs_new (const char *volname) return NULL; } - fs = CALLOC (1, sizeof (*fs)); + fs = glfs_new_fs (volname); if (!fs) return NULL; - ret = pthread_mutex_init (&fs->mutex, NULL); - if (ret != 0) - goto freefs; - - ret = pthread_cond_init (&fs->cond, NULL); - if (ret != 0) - goto mutex_destroy; - - ret = pthread_cond_init (&fs->child_down_cond, NULL); - if (ret != 0) - goto cond_destroy; - - ret = pthread_mutex_init (&fs->upcall_list_mutex, NULL); - if (ret != 0) - goto cond_child_destroy; - ctx = glusterfs_ctx_new (); if (!ctx) goto fini; @@ -654,39 +668,9 @@ pub_glfs_new (const char *volname) if (!(fs->ctx->cmd_args.volfile_id)) goto fini; - fs->volname = strdup (volname); - if (!fs->volname) - goto fini; - - INIT_LIST_HEAD (&fs->openfds); - INIT_LIST_HEAD (&fs->upcall_list); - - fs->pin_refcnt = 0; - goto out; -cond_child_destroy: - pthread_cond_destroy (&fs->child_down_cond); - -cond_destroy: - pthread_cond_destroy (&fs->cond); - -mutex_destroy: - pthread_mutex_destroy (&fs->mutex); - -freefs: - FREE (fs); - fs = NULL; - goto out; fini: - /* - * When pthread_*init() fails there is no way for other cleanup - * funtions (glfs_fini/glfs_free_from_ctx) to know which of them succeded - * and which did not(unless there is a flag). Hence pthread cleanup is done - * in this funtion.Anything that fails after pthread_*_init() succeeds, should - * directly call glfs_fini() to cleanup the resources. - */ - glfs_fini (fs); fs = NULL; out: @@ -705,25 +689,15 @@ priv_glfs_new_from_ctx (glusterfs_ctx_t *ctx) struct glfs *fs = NULL; if (!ctx) - return NULL; + goto out; - fs = CALLOC (1, sizeof (*fs)); + fs = glfs_new_fs (""); if (!fs) - return NULL; - fs->ctx = ctx; - - (void) pthread_cond_init (&fs->cond, NULL); - (void) pthread_cond_init (&fs->child_down_cond, NULL); - - (void) pthread_mutex_init (&fs->mutex, NULL); - - INIT_LIST_HEAD (&fs->openfds); - - INIT_LIST_HEAD (&fs->upcall_list); - pthread_mutex_init (&fs->upcall_list_mutex, NULL); + goto out; - fs->pin_refcnt = 0; + fs->ctx = ctx; +out: return fs; } @@ -747,15 +721,18 @@ priv_glfs_free_from_ctx (struct glfs *fs) GF_FREE (u_list->upcall_data.data); GF_FREE (u_list); } - (void) pthread_mutex_destroy (&fs->upcall_list_mutex); - (void) pthread_cond_destroy (&fs->cond); - (void) pthread_cond_destroy (&fs->child_down_cond); + PTHREAD_MUTEX_DESTROY (&fs->mutex, fs->pthread_flags, GLFS_INIT_MUTEX); + + PTHREAD_COND_DESTROY (&fs->cond, fs->pthread_flags, GLFS_INIT_COND); + + PTHREAD_COND_DESTROY (&fs->child_down_cond, fs->pthread_flags, + GLFS_INIT_COND_CHILD); - (void) pthread_mutex_destroy (&fs->mutex); + PTHREAD_MUTEX_DESTROY (&fs->upcall_list_mutex, fs->pthread_flags, + GLFS_INIT_MUTEX_UPCALL); - if (fs->volname) - FREE (fs->volname); + FREE (fs->volname); FREE (fs); } |