* Fix pthread key creation to depend on if it hasn't been created before

instead of depending if a lock was succesfully acquired.  Also, add
  a comment explaining why it is such complex (for all I could guess).
* replace err()'s with abort()
* replace some abort()'s by returning failure
This commit is contained in:
pooka 2007-11-05 13:38:27 +00:00
parent 08de5799c0
commit 8f078f842e
1 changed files with 25 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: refuse.c,v 1.79 2007/10/28 18:41:54 pooka Exp $ */
/* $NetBSD: refuse.c,v 1.80 2007/11/05 13:38:27 pooka Exp $ */
/*
* Copyright © 2007 Alistair Crooks. All rights reserved.
@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#if !defined(lint)
__RCSID("$NetBSD: refuse.c,v 1.79 2007/10/28 18:41:54 pooka Exp $");
__RCSID("$NetBSD: refuse.c,v 1.80 2007/11/05 13:38:27 pooka Exp $");
#endif /* !lint */
#include <assert.h>
@ -154,7 +154,7 @@ static ino_t fakeino = 3;
#ifdef MULTITHREADED_REFUSE
static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t context_key;
static uint64_t context_refc;
static unsigned long context_refc;
#endif
/* return the fuse_context struct related to this thread */
@ -166,7 +166,7 @@ fuse_get_context(void)
if ((ctxt = pthread_getspecific(context_key)) == NULL) {
if ((ctxt = calloc(1, sizeof(struct fuse_context))) == NULL) {
errx(EXIT_FAILURE, "fuse_get_context: no memory");
abort();
}
pthread_setspecific(context_key, ctxt);
}
@ -187,13 +187,20 @@ free_context(void *ctxt)
}
#endif
/* make the pthread key */
/*
* Create the pthread key. The reason for the complexity is to
* enable use of multiple fuse instances within a single process.
*/
static int
create_context_key(void)
{
#ifdef MULTITHREADED_REFUSE
if (pthread_mutex_lock(&context_mutex) == 0) {
/* we have the lock, attempt to create the key */
int rv;
rv = pthread_mutex_lock(&context_mutex);
assert(rv == 0);
if (context_refc == 0) {
if (pthread_key_create(&context_key, free_context) != 0) {
warnx("create_context_key: pthread_key_create failed");
pthread_mutex_unlock(&context_mutex);
@ -208,12 +215,12 @@ create_context_key(void)
#endif
}
/* delete the pthread key */
static void
delete_context_key(void)
{
#ifdef MULTITHREADED_REFUSE
pthread_mutex_lock(&context_mutex);
/* If we are the last fuse instances using the key, delete it */
if (--context_refc == 0) {
free(pthread_getspecific(context_key));
pthread_key_delete(context_key);
@ -260,7 +267,7 @@ fill_dirbuf(struct puffs_fuse_dirh *dh, const char *name, ino_t dino,
/* initial? */
if (dh->bufsize == 0) {
if ((dh->dbuf = calloc(1, DIR_CHUNKSIZE)) == NULL) {
err(EXIT_FAILURE, "fill_dirbuf");
abort();
}
dh->d = dh->dbuf;
dh->reslen = dh->bufsize = DIR_CHUNKSIZE;
@ -273,7 +280,7 @@ fill_dirbuf(struct puffs_fuse_dirh *dh, const char *name, ino_t dino,
/* try to increase buffer space */
dh->dbuf = realloc(dh->dbuf, dh->bufsize + DIR_CHUNKSIZE);
if (dh->dbuf == NULL) {
err(EXIT_FAILURE, "fill_dirbuf realloc");
abort();
}
dh->d = (void *)((uint8_t *)dh->dbuf + (dh->bufsize - dh->reslen));
dh->reslen += DIR_CHUNKSIZE;
@ -367,7 +374,7 @@ fuse_setup(int argc, char **argv, const struct fuse_operations *ops,
/* grab the pthread context key */
if (!create_context_key()) {
err(EXIT_FAILURE, "fuse_setup: can't create context key");
return NULL;
}
/* stuff name into fuse_args */
@ -376,7 +383,8 @@ fuse_setup(int argc, char **argv, const struct fuse_operations *ops,
free(args->argv[0]);
}
if ((args->argv[0] = strdup(name)) == NULL) {
err(EXIT_FAILURE, "fuse_setup: can't strdup memory");
fuse_opt_free_args(args);
return NULL;
}
/* count back from the end over arguments starting with '-' */
@ -1373,6 +1381,11 @@ void
fuse_destroy(struct fuse *fuse)
{
/*
* TODO: needs to assert the fs is quiescent, i.e. no other
* threads exist
*/
delete_context_key();
/* XXXXXX: missing stuff */
free(fuse);