summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPino Toscano <toscano.pino@tiscali.it>2013-03-30 15:28:07 +0100
committerPino Toscano <toscano.pino@tiscali.it>2013-03-30 15:28:07 +0100
commit748ef0df0ae891c65043a2a3c8d0f29cad358f5a (patch)
tree02a3725d7e1885d063474de92db351e90c03863b
parentcd50c0de1db93520000bfb907caf07e51aa6cec5 (diff)
Switch from __thread to pthread_key_t for fuse_contextlibfuse/pinotree/fuse-improvements/master
This allows to properly cleanup the per-thread context. * src/fuse_i.h (libfuse_ctx): Remove declaration. * src/main.c (libfuse_ctx): Remove variable. (libfuse_ctx_key): New variable. (fuse_destroy_context): New function. (fuse_create_key): Likewise. (fuse_new): Use fuse_get_context instead of libfuse_ctx. (fuse_get_context): Create fuse_create_key only once. Allocate a new struct fuse_context if needed, and return it. * src/netfs.c (update_context_struct): Use fuse_get_context instead of libfuse_ctx.
-rw-r--r--src/fuse_i.h2
-rw-r--r--src/main.c45
-rw-r--r--src/netfs.c18
3 files changed, 43 insertions, 22 deletions
diff --git a/src/fuse_i.h b/src/fuse_i.h
index 472bc6503..851058d65 100644
--- a/src/fuse_i.h
+++ b/src/fuse_i.h
@@ -57,8 +57,6 @@ extern struct fuse *libfuse_fuse;
#define FUSE_SYMVER(x) __asm__(x)
-extern __thread struct fuse_context *libfuse_ctx;
-
extern void update_context_struct(struct iouser *cred, struct fuse *fuse);
/*****************************************************************************
diff --git a/src/main.c b/src/main.c
index b8f25c8cd..345845cb0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,7 +35,8 @@ struct _libfuse_params libfuse_params = { 0 };
/* pointer to the fuse structure of this translator process */
struct fuse *libfuse_fuse = NULL;
-__thread struct fuse_context *libfuse_ctx;
+/* the key for the fuse_context */
+static pthread_key_t libfuse_ctx_key;
/* the port where to write out debug messages to, NULL to omit these */
FILE *debug_port = NULL;
@@ -44,6 +45,25 @@ FILE *debug_port = NULL;
static int fuse_bootstrap(const char *mountpoint);
+/* Destroy the fuse_context held as TSD.
+ */
+static void
+fuse_destroy_context(void *data)
+{
+ free(data);
+}
+
+
+/* Create the TSD key.
+ */
+static void
+fuse_create_key(void)
+{
+ int err = pthread_key_create(&libfuse_ctx_key, fuse_destroy_context);
+ assert_perror(err);
+}
+
+
/* Interpret a __single__ mount option
* The option itself `opt' may be modified during this call.
*/
@@ -322,7 +342,7 @@ fuse_new(struct fuse_chan *ch, struct fuse_args *args,
new->conn.max_readahead = UINT_MAX;
update_context_struct(NULL, new);
- libfuse_ctx->private_data = user_data;
+ fuse_get_context()->private_data = user_data;
if(new->op.ops.init != NULL)
{
@@ -582,7 +602,26 @@ fuse_exited(struct fuse *f)
struct fuse_context *
fuse_get_context(void)
{
- return libfuse_ctx;
+ static pthread_once_t libfuse_ctx_key_once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&libfuse_ctx_key_once, fuse_create_key);
+
+ struct fuse_context *ctx = pthread_getspecific(libfuse_ctx_key);
+
+ if(! ctx)
+ {
+ ctx = calloc(1, sizeof(*ctx));
+ if(! ctx)
+ {
+ fprintf(stderr, "Cannot allocate a new fuse_context\n");
+ fprintf(stderr, "libfuse will abort now\n");
+ abort();
+ }
+
+ pthread_setspecific(libfuse_ctx_key, ctx);
+ }
+
+ return ctx;
}
diff --git a/src/netfs.c b/src/netfs.c
index a8718369c..9a11dfcf4 100644
--- a/src/netfs.c
+++ b/src/netfs.c
@@ -61,24 +61,8 @@ void
update_context_struct(struct iouser *cred, struct fuse *fuse)
{
FUNC_PROLOGUE("refresh_context_struct");
- struct fuse_context *ctx = libfuse_ctx;
+ struct fuse_context *ctx = fuse_get_context();
- if(! ctx)
- {
- ctx = malloc(sizeof(struct fuse_context));
- if(! ctx)
- {
- perror(PACKAGE_NAME);
- return;
- }
-
- libfuse_ctx = ctx;
-
- /* FIXME, how to figure out the pid of the program asking for the
- * filesystem operation? */
- ctx->pid = 0;
- }
-
ctx->fuse = fuse;
ctx->private_data = ctx->fuse ? ctx->fuse->private_data : NULL;