aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2004-06-30 11:34:56 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2004-06-30 11:34:56 +0000
commit65cf7c7deb7a98dc31beb39db3c1ae1cba45b69f (patch)
tree2d931189dd72123c5d746dcea8c592548ad442dc
parent556d03d97b0689ee32cc20d35e8715e655745c80 (diff)
support for multiplexing fuse fd
-rw-r--r--ChangeLog6
-rw-r--r--include/fuse.h1
-rw-r--r--lib/fuse.c61
-rw-r--r--lib/fuse_mt.c2
4 files changed, 41 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 6786d2e..5448cc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
* Acquire inode->i_sem before open and release methods to prevent
concurrent rename or unlink operations.
+ * Make __fuse_read_cmd() read only one command. This allows
+ multiplexing the fuse file descriptor with other event sources
+ using select() or poll() (patch by Jeff Harris)
+
+ * Export 'exited' flag with __fuse_exited() (patch by Jeff Harris)
+
2004-06-27 Miklos Szeredi <mszeredi@inf.bme.hu>
* Fix file offset wrap around at 4G when doing large reads
diff --git a/include/fuse.h b/include/fuse.h
index d298cb3..aeeb204 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -273,6 +273,7 @@ typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
struct fuse_cmd *__fuse_read_cmd(struct fuse *f);
void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd);
void __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data);
+int __fuse_exited(struct fuse* f);
#ifdef __cplusplus
}
diff --git a/lib/fuse.c b/lib/fuse.c
index d4e95f2..4cd8915 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1432,6 +1432,11 @@ void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
free_cmd(cmd);
}
+int __fuse_exited(struct fuse* f)
+{
+ return f->exited;
+}
+
struct fuse_cmd *__fuse_read_cmd(struct fuse *f)
{
ssize_t res;
@@ -1444,36 +1449,36 @@ struct fuse_cmd *__fuse_read_cmd(struct fuse *f)
in = (struct fuse_in_header *) cmd->buf;
inarg = cmd->buf + sizeof(struct fuse_in_header);
- do {
- res = read(f->fd, cmd->buf, FUSE_MAX_IN);
- if (res == -1) {
- free_cmd(cmd);
- if (f->exited || errno == EINTR)
- return NULL;
-
- /* ENODEV means we got unmounted, so we silenty return failure */
- if (errno != ENODEV) {
- /* BAD... This will happen again */
- perror("fuse: reading device");
- }
-
- fuse_exit(f);
- return NULL;
- }
- if ((size_t) res < sizeof(struct fuse_in_header)) {
- free_cmd(cmd);
- /* Cannot happen */
- fprintf(stderr, "short read on fuse device\n");
- fuse_exit(f);
+ res = read(f->fd, cmd->buf, FUSE_MAX_IN);
+ if (res == -1) {
+ free_cmd(cmd);
+ if (__fuse_exited(f) || errno == EINTR)
return NULL;
+
+ /* ENODEV means we got unmounted, so we silenty return failure */
+ if (errno != ENODEV) {
+ /* BAD... This will happen again */
+ perror("fuse: reading device");
}
- cmd->buflen = res;
- /* Forget is special, it can be done without messing with threads. */
- if (in->opcode == FUSE_FORGET)
- do_forget(f, in, (struct fuse_forget_in *) inarg);
-
- } while (in->opcode == FUSE_FORGET);
+ fuse_exit(f);
+ return NULL;
+ }
+ if ((size_t) res < sizeof(struct fuse_in_header)) {
+ free_cmd(cmd);
+ /* Cannot happen */
+ fprintf(stderr, "short read on fuse device\n");
+ fuse_exit(f);
+ return NULL;
+ }
+ cmd->buflen = res;
+
+ /* Forget is special, it can be done without messing with threads. */
+ if (in->opcode == FUSE_FORGET) {
+ do_forget(f, in, (struct fuse_forget_in *) inarg);
+ free_cmd(cmd);
+ return NULL;
+ }
return cmd;
}
@@ -1486,7 +1491,7 @@ void fuse_loop(struct fuse *f)
while (1) {
struct fuse_cmd *cmd;
- if (f->exited)
+ if (__fuse_exited(f))
return;
cmd = __fuse_read_cmd(f);
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index afc70d4..597ce1a 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -38,7 +38,7 @@ static void *do_work(void *data)
while (1) {
struct fuse_cmd *cmd;
- if (f->exited)
+ if (__fuse_exited(f))
break;
cmd = __fuse_read_cmd(w->f);