in fs/fuse_adaptor.cpp [938:994]
int run_fuse(int argc, char *argv[], const struct ::fuse_operations *op,
void *user_data) {
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct user_config cfg{ .threads = 4, };
fuse_opt_parse(&args, &cfg, user_opts, NULL);
struct fuse *fuse;
struct fuse_session* se;
char *mountpoint;
int multithreaded;
int res;
size_t op_size = sizeof(*(op));
#if FUSE_USE_VERSION < 30
fuse = fuse_setup(args.argc, args.argv, op, op_size, &mountpoint, &multithreaded, user_data);
#else
fuse = fuse3_setup(args.argc, args.argv, op, op_size, &mountpoint, &multithreaded, user_data);
#endif
if (fuse == NULL) return 1;
if (multithreaded) {
if (cfg.threads < 1) cfg.threads = 1;
if (cfg.threads > 64) cfg.threads = 64;
se = fuse_get_session(fuse);
#if FUSE_USE_VERSION < 30
auto ch = fuse_session_next_chan(se, NULL);
auto fd = fuse_chan_fd(ch);
#else
auto fd = fuse_session_fd(se);
#endif
int flags = fcntl(fd, F_GETFL, 0);
if (flags >= 0) fcntl(fd, F_SETFL, flags | O_NONBLOCK);
std::vector<std::thread> ths;
for (int i = 0; i < cfg.threads; ++i) {
ths.emplace_back(std::thread([&]() {
init(INIT_EVENT_EPOLL, INIT_IO_LIBAIO);
DEFER(fini());
if (fuse_session_loop_mpt(se) != 0) res = -1;
}));
}
for (auto& th : ths) th.join();
fuse_session_reset(se);
} else {
se = fuse_get_session(fuse);
res = fuse_session_loop_mpt(se);
fuse_session_reset(se);
}
fuse_remove_signal_handlers(fuse_get_session(fuse));
#if FUSE_USE_VERSION < 30
fuse_unmount(mountpoint, fuse_session_next_chan(se, NULL));
#else
fuse_unmount(fuse);
#endif
fuse_destroy(fuse);
free(mountpoint);
fuse_opt_free_args(&args);
if (res == -1) return 1;
return 0;
}