summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs-internal.h50
-rw-r--r--api/src/glfs.c123
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);
}