threading fixes
diff --git a/example/fusexmp.c b/example/fusexmp.c
index aeb4f88..2bcdb37 100644
--- a/example/fusexmp.c
+++ b/example/fusexmp.c
@@ -231,8 +231,32 @@
return res;
}
+
+static struct fuse_operations xmp_oper = {
+ getattr: xmp_getattr,
+ readlink: xmp_readlink,
+ getdir: xmp_getdir,
+ mknod: xmp_mknod,
+ mkdir: xmp_mkdir,
+ symlink: xmp_symlink,
+ unlink: xmp_unlink,
+ rmdir: xmp_rmdir,
+ rename: xmp_rename,
+ link: xmp_link,
+ chmod: xmp_chmod,
+ chown: xmp_chown,
+ truncate: xmp_truncate,
+ utime: xmp_utime,
+ open: xmp_open,
+ read: xmp_read,
+ write: xmp_write,
+};
+
+
static void exit_handler()
{
+ close(0);
+ system(unmount_cmd);
exit(0);
}
@@ -260,32 +284,6 @@
}
}
-static struct fuse_operations xmp_oper = {
- getattr: xmp_getattr,
- readlink: xmp_readlink,
- getdir: xmp_getdir,
- mknod: xmp_mknod,
- mkdir: xmp_mkdir,
- symlink: xmp_symlink,
- unlink: xmp_unlink,
- rmdir: xmp_rmdir,
- rename: xmp_rename,
- link: xmp_link,
- chmod: xmp_chmod,
- chown: xmp_chown,
- truncate: xmp_truncate,
- utime: xmp_utime,
- open: xmp_open,
- read: xmp_read,
- write: xmp_write,
-};
-
-static void cleanup()
-{
- close(0);
- system(unmount_cmd);
-}
-
int main(int argc, char *argv[])
{
int argctr;
@@ -307,7 +305,6 @@
unmount_cmd = argv[argctr++];
set_signal_handlers();
- atexit(cleanup);
flags = 0;
multithreaded = 1;
diff --git a/include/fuse.h b/include/fuse.h
index e284469..0bf09e1 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -135,9 +135,9 @@
void fuse_destroy(struct fuse *f);
-/* --------------------------------------------------- *
- * Advanced API, usually you need not bother with this *
- * --------------------------------------------------- */
+/* ----------------------------------------------------------- *
+ * Advanced API for event handling, don't worry about this... *
+ * ----------------------------------------------------------- */
struct fuse_cmd;
diff --git a/lib/fuse.c b/lib/fuse.c
index 6bd32ae..8ea13ad 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -412,7 +412,7 @@
send_reply(f, in, res, &arg, sizeof(arg));
}
-int do_chmod(struct fuse *f, const char *path, struct fuse_attr *attr)
+static int do_chmod(struct fuse *f, const char *path, struct fuse_attr *attr)
{
int res;
@@ -423,7 +423,7 @@
return res;
}
-int do_chown(struct fuse *f, const char *path, struct fuse_attr *attr,
+static int do_chown(struct fuse *f, const char *path, struct fuse_attr *attr,
int valid)
{
int res;
@@ -437,7 +437,8 @@
return res;
}
-int do_truncate(struct fuse *f, const char *path, struct fuse_attr *attr)
+static int do_truncate(struct fuse *f, const char *path,
+ struct fuse_attr *attr)
{
int res;
@@ -448,7 +449,7 @@
return res;
}
-int do_utime(struct fuse *f, const char *path, struct fuse_attr *attr)
+static int do_utime(struct fuse *f, const char *path, struct fuse_attr *attr)
{
int res;
struct utimbuf buf;
@@ -908,7 +909,6 @@
void fuse_destroy(struct fuse *f)
{
- /* FIXME: Kill all threads... */
size_t i;
for(i = 0; i < f->ino_table_size; i++) {
struct node *node;
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index ac616fe..6afc3bc 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -13,25 +13,27 @@
#include <string.h>
#include <errno.h>
#include <pthread.h>
+#include <semaphore.h>
#include <signal.h>
#include <sys/time.h>
-
struct thread_common {
struct fuse *f;
struct fuse_cmd *cmd;
pthread_mutex_t lock;
pthread_cond_t cond;
+ sem_t started;
int avail;
};
-/* Called with c->lock held */
static void *do_work(void *data)
{
struct thread_common *c = (struct thread_common *) data;
- struct fuse *f = c->f;
+ pthread_mutex_lock(&c->lock);
+ sem_post(&c->started);
c->avail ++;
+
while(1) {
int res;
struct timespec timeout;
@@ -52,13 +54,13 @@
c->cmd = NULL;
c->avail --;
pthread_mutex_unlock(&c->lock);
- __fuse_process_cmd(f, cmd);
+ __fuse_process_cmd(c->f, cmd);
pthread_mutex_lock(&c->lock);
c->avail ++;
}
c->avail --;
- pthread_mutex_unlock(&c->lock);
+ pthread_mutex_unlock(&c->lock);
return NULL;
}
@@ -70,19 +72,23 @@
sigset_t newset;
int res;
+ pthread_mutex_unlock(&c->lock);
+
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* Disallow signal reception in worker threads */
sigfillset(&newset);
- sigprocmask(SIG_SETMASK, &newset, &oldset);
+ pthread_sigmask(SIG_SETMASK, &newset, &oldset);
res = pthread_create(&thrid, &attr, do_work, c);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- pthread_mutex_lock(&c->lock);
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
if(res != 0) {
fprintf(stderr, "Error creating thread: %s\n", strerror(res));
exit(1);
}
+
+ sem_wait(&c->started);
+ pthread_mutex_lock(&c->lock);
}
void fuse_loop_mt(struct fuse *f)
@@ -94,6 +100,7 @@
c->cmd = NULL;
pthread_cond_init(&c->cond, NULL);
pthread_mutex_init(&c->lock, NULL);
+ sem_init(&c->started, 0, 0);
c->avail = 0;
while(1) {
@@ -102,9 +109,9 @@
exit(1);
pthread_mutex_lock(&c->lock);
- c->cmd = cmd;
while(c->avail == 0)
start_thread(c);
+ c->cmd = cmd;
pthread_cond_signal(&c->cond);
pthread_mutex_unlock(&c->lock);
}