From 680a69a8be8b7dd9bf1beae4e48e927d0fb1cd7f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 16 Nov 2001 13:31:14 +0000 Subject: [PATCH] threading fixes --- example/fusexmp.c | 51 ++++++++++++++++++++++------------------------- include/fuse.h | 6 +++--- lib/fuse.c | 10 +++++----- lib/fuse_mt.c | 25 ++++++++++++++--------- 4 files changed, 48 insertions(+), 44 deletions(-) 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 @@ static int xmp_write(const char *path, const char *buf, size_t size, 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 void set_signal_handlers() } } -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 @@ int main(int argc, char *argv[]) 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_loop_mt(struct fuse *f); 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 @@ static void do_getattr(struct fuse *f, struct fuse_in_header *in) 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 @@ int do_chmod(struct fuse *f, const char *path, struct fuse_attr *attr) 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 @@ int do_chown(struct fuse *f, const char *path, struct fuse_attr *attr, 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 @@ int do_truncate(struct fuse *f, const char *path, struct fuse_attr *attr) 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_set_operations(struct fuse *f, const struct fuse_operations *op) 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 #include #include +#include #include #include - 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 @@ static void *do_work(void *data) 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 @@ static void start_thread(struct thread_common *c) 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 @@ void fuse_loop_mt(struct fuse *f) 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 @@ void fuse_loop_mt(struct fuse *f) 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); } -- 2.30.2