diff options
author | Pino Toscano <toscano.pino@tiscali.it> | 2013-03-30 15:28:07 +0100 |
---|---|---|
committer | Pino Toscano <toscano.pino@tiscali.it> | 2013-03-30 15:28:07 +0100 |
commit | 748ef0df0ae891c65043a2a3c8d0f29cad358f5a (patch) | |
tree | 02a3725d7e1885d063474de92db351e90c03863b | |
parent | cd50c0de1db93520000bfb907caf07e51aa6cec5 (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.h | 2 | ||||
-rw-r--r-- | src/main.c | 45 | ||||
-rw-r--r-- | 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; |