fix lookup Oops
[fuse.git] / lib / fuse_mt.c
blobee8ef402a85c7b44e0b794fabe427c55e86fa71e
1 /*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU LGPL.
6 See the file COPYING.LIB.
7 */
9 #include "fuse_i.h"
10 #include "fuse_lowlevel.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <pthread.h>
16 #include <assert.h>
18 struct procdata {
19 struct fuse *f;
20 struct fuse_chan *prevch;
21 struct fuse_session *prevse;
22 fuse_processor_t proc;
23 void *data;
26 static void mt_session_proc(void *data, const char *buf, size_t len,
27 struct fuse_chan *ch)
29 struct procdata *pd = (struct procdata *) data;
30 struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
32 (void) len;
33 cmd->ch = ch;
34 pd->proc(pd->f, cmd, pd->data);
37 static void mt_session_exit(void *data, int val)
39 struct procdata *pd = (struct procdata *) data;
40 if (val)
41 fuse_session_exit(pd->prevse);
42 else
43 fuse_session_reset(pd->prevse);
46 static int mt_session_exited(void *data)
48 struct procdata *pd = (struct procdata *) data;
49 return fuse_session_exited(pd->prevse);
52 static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
54 struct fuse_cmd *cmd;
55 struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
57 assert(size >= sizeof(cmd));
59 cmd = fuse_read_cmd(pd->f);
60 if (cmd == NULL)
61 return 0;
63 *(struct fuse_cmd **) buf = cmd;
65 return sizeof(cmd);
68 static int mt_chan_send(struct fuse_chan *ch, const struct iovec iov[],
69 size_t count)
71 struct procdata *pd = (struct procdata *) fuse_chan_data(ch);
72 return fuse_chan_send(pd->prevch, iov, count);
75 int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
77 int res;
78 struct procdata pd;
79 struct fuse_session *prevse = fuse_get_session(f);
80 struct fuse_session *se;
81 struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
82 struct fuse_chan *ch;
83 struct fuse_session_ops sop = {
84 .exit = mt_session_exit,
85 .exited = mt_session_exited,
86 .process = mt_session_proc,
88 struct fuse_chan_ops cop = {
89 .receive = mt_chan_receive,
90 .send = mt_chan_send,
93 pd.f = f;
94 pd.prevch = prevch;
95 pd.prevse = prevse;
96 pd.proc = proc;
97 pd.data = data;
99 se = fuse_session_new(&sop, &pd);
100 if (se == NULL)
101 return -1;
103 ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), sizeof(struct fuse_cmd *),
104 &pd);
105 if (ch == NULL) {
106 fuse_session_destroy(se);
107 return -1;
109 fuse_session_add_chan(se, ch);
110 res = fuse_session_loop_mt(se);
111 fuse_session_destroy(se);
112 return res;
115 int fuse_loop_mt(struct fuse *f)
117 if (f == NULL)
118 return -1;
120 return fuse_session_loop_mt(fuse_get_session(f));
123 __asm__(".symver fuse_loop_mt_proc,__fuse_loop_mt@");