diff options
author | Nikolaus Rath <Nikolaus@rath.org> | 2016-10-03 20:27:02 -0700 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2016-10-03 23:01:46 -0700 |
commit | e4015aca9b7ba0c787ad8d07f7d9db18d3bbc211 (patch) | |
tree | 579aa5f63874d979ec7b233214dbb0ee8debf260 /lib/fuse_loop_mt.c | |
parent | e572cfbd3490add057b867c29d37da51ee8217e5 (diff) |
Merge master fuse_chan into fuse_session.
This is a code simplification patch.
- It confines most of the implementation channel implementation into
fuse_loop_mt (which is its only user).
- It makes it more obvious in the code that channels are only ever used
when using -o clone_fd and multi-threaded main loop.
- It simplies the definition of both struct fuse_session and struct
fuse_chan.
- Theoretically it should result in (minuscule) performance
improvements when not using -o clone_fd.
- Overall, it removes a lot more lines of source code than it adds :-).
Diffstat (limited to 'lib/fuse_loop_mt.c')
-rw-r--r-- | lib/fuse_loop_mt.c | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c index 1d9a5f0..c925cd7 100644 --- a/lib/fuse_loop_mt.c +++ b/lib/fuse_loop_mt.c @@ -23,6 +23,7 @@ #include <errno.h> #include <sys/time.h> #include <sys/ioctl.h> +#include <assert.h> /* Environment var controlling the thread stack size */ #define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK" @@ -42,13 +43,53 @@ struct fuse_mt { int numworker; int numavail; struct fuse_session *se; - struct fuse_chan *prevch; struct fuse_worker main; sem_t finish; int exit; int error; }; +static struct fuse_chan *fuse_chan_new(int fd) +{ + struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch)); + if (ch == NULL) { + fprintf(stderr, "fuse: failed to allocate channel\n"); + return NULL; + } + + memset(ch, 0, sizeof(*ch)); + ch->fd = fd; + ch->ctr = 1; + fuse_mutex_init(&ch->lock); + + return ch; +} + +struct fuse_chan *fuse_chan_get(struct fuse_chan *ch) +{ + assert(ch->ctr > 0); + pthread_mutex_lock(&ch->lock); + ch->ctr++; + pthread_mutex_unlock(&ch->lock); + + return ch; +} + +void fuse_chan_put(struct fuse_chan *ch) +{ + if (ch == NULL) + return; + pthread_mutex_lock(&ch->lock); + ch->ctr--; + if (!ch->ctr) { + pthread_mutex_unlock(&ch->lock); + close(ch->fd); + pthread_mutex_destroy(&ch->lock); + free(ch); + } else + pthread_mutex_unlock(&ch->lock); +} + static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next) { struct fuse_worker *prev = next->prev; @@ -195,15 +236,13 @@ static struct fuse_chan *fuse_clone_chan(struct fuse_mt *mt) } fcntl(clonefd, F_SETFD, FD_CLOEXEC); - masterfd = mt->prevch->fd; + masterfd = mt->se->fd; res = ioctl(clonefd, FUSE_DEV_IOC_CLONE, &masterfd); if (res == -1) { fprintf(stderr, "fuse: failed to clone device fd: %s\n", strerror(errno)); close(clonefd); - mt->se->f->clone_fd = 0; - - return fuse_chan_get(mt->prevch); + return NULL; } newch = fuse_chan_new(clonefd); if (newch == NULL) @@ -225,13 +264,15 @@ static int fuse_loop_start_thread(struct fuse_mt *mt) w->fbuf.mem = NULL; w->mt = mt; - + w->ch = NULL; if (mt->se->f->clone_fd) { w->ch = fuse_clone_chan(mt); - if (!w->ch) - return -1; - } else { - w->ch = fuse_chan_get(mt->prevch); + if(!w->ch) { + /* Don't attempt this again */ + fprintf(stderr, "fuse: trying to continue " + "without -o clone_fd.\n"); + mt->se->f->clone_fd = 0; + } } res = fuse_start_thread(&w->thread_id, fuse_do_work, w); @@ -266,7 +307,6 @@ int fuse_session_loop_mt(struct fuse_session *se) memset(&mt, 0, sizeof(struct fuse_mt)); mt.se = se; - mt.prevch = fuse_session_chan(se); mt.error = 0; mt.numworker = 0; mt.numavail = 0; |