diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-17 15:56:05 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-17 15:56:05 +0000 |
commit | 8d975f6fb3f54c82f295b5e44391637a7c008345 (patch) | |
tree | b86bb953018aaf573bb88df08cd48df97bc02d75 /lib/fuse_loop_mt.c | |
parent | 6f385414b27e929bd14435ea8342cde4bae0ef8d (diff) |
fix
Diffstat (limited to 'lib/fuse_loop_mt.c')
-rw-r--r-- | lib/fuse_loop_mt.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c index 16be149..fc8f892 100644 --- a/lib/fuse_loop_mt.c +++ b/lib/fuse_loop_mt.c @@ -24,7 +24,6 @@ struct fuse_worker { int numworker; int numavail; struct fuse_session *se; - struct fuse_chan *ch; struct fuse_chan *prevch; pthread_t threads[FUSE_MAX_WORKERS]; pthread_t main_thread; @@ -32,6 +31,11 @@ struct fuse_worker { int error; }; +struct fuse_wchan { + struct fuse_worker *w; + struct fuse_chan *prevch; +}; + #ifndef USE_UCLIBC #define mutex_init(mut) pthread_mutex_init(mut, NULL) #else @@ -48,11 +52,15 @@ static void mutex_init(pthread_mutex_t *mut) static int fuse_loop_mt_send(struct fuse_chan *ch, const struct iovec iov[], size_t count) { - struct fuse_worker *w = (struct fuse_worker *) fuse_chan_data(ch); - pthread_mutex_lock(&w->lock); - w->numavail ++; - pthread_mutex_unlock(&w->lock); - return fuse_chan_send(w->prevch, iov, count); + int res; + struct fuse_wchan *wchan_data = (struct fuse_wchan *) fuse_chan_data(ch); + pthread_mutex_lock(&wchan_data->w->lock); + wchan_data->w->numavail ++; + pthread_mutex_unlock(&wchan_data->w->lock); + res = fuse_chan_send(wchan_data->prevch, iov, count); + fuse_chan_destroy(ch); + free(wchan_data); + return res; } static int start_thread(struct fuse_worker *w, pthread_t *thread_id); @@ -74,7 +82,11 @@ static void *do_work(void *data) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); while (!fuse_session_exited(w->se)) { - int res = fuse_chan_recv(w->prevch, buf, bufsize); + struct fuse_chan *ch = w->prevch; + struct fuse_chan *wchan; + struct fuse_wchan *wchan_data; + struct fuse_chan_ops cop = { .send = fuse_loop_mt_send }; + int res = fuse_chan_recv(&ch, buf, bufsize); if (res == -EINTR) continue; if (res <= 0) { @@ -105,7 +117,17 @@ static void *do_work(void *data) } } pthread_mutex_unlock(&w->lock); - fuse_session_process(w->se, buf, res, w->ch); + wchan_data = malloc(sizeof(struct fuse_wchan)); + wchan = fuse_chan_new(&cop, -1, fuse_chan_bufsize(ch), wchan_data); + if (!wchan_data || !wchan) { + free(wchan_data); + fuse_session_exit(w->se); + w->error = -1; + break; + } + wchan_data->w = w; + wchan_data->prevch = ch; + fuse_session_process(w->se, buf, res, wchan); } pthread_cleanup_pop(1); @@ -145,10 +167,6 @@ int fuse_session_loop_mt(struct fuse_session *se) int i; int err; struct fuse_worker *w; - struct fuse_chan_ops cop = { - .send = fuse_loop_mt_send, - }; - w = (struct fuse_worker *) malloc(sizeof(struct fuse_worker)); if (w == NULL) { fprintf(stderr, "fuse: failed to allocate worker structure\n"); @@ -157,11 +175,6 @@ int fuse_session_loop_mt(struct fuse_session *se) memset(w, 0, sizeof(struct fuse_worker)); w->se = se; w->prevch = fuse_session_next_chan(se, NULL); - w->ch = fuse_chan_new(&cop, -1, fuse_chan_bufsize(w->prevch), w); - if (w->ch == NULL) { - free(w); - return -1; - } w->error = 0; w->numworker = 1; w->numavail = 1; @@ -179,7 +192,6 @@ int fuse_session_loop_mt(struct fuse_session *se) pthread_join(w->threads[i], NULL); pthread_mutex_destroy(&w->lock); err = w->error; - fuse_chan_destroy(w->ch); free(w); fuse_session_reset(se); return err; |