From 748ef0df0ae891c65043a2a3c8d0f29cad358f5a Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sat, 30 Mar 2013 15:28:07 +0100 Subject: Switch from __thread to pthread_key_t for fuse_context 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. --- src/fuse_i.h | 2 -- src/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/netfs.c | 18 +----------------- 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; -- cgit v1.2.3