aboutsummaryrefslogtreecommitdiff
path: root/lib/fuse_loop_mt.c
diff options
context:
space:
mode:
authorGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-03 20:27:02 -0700
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-03 23:01:46 -0700
commite4015aca9b7ba0c787ad8d07f7d9db18d3bbc211 (patch)
tree579aa5f63874d979ec7b233214dbb0ee8debf260 /lib/fuse_loop_mt.c
parente572cfbd3490add057b867c29d37da51ee8217e5 (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.c62
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;