You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.5 KiB

  1. /*
  2. FUSE: Filesystem in Userspace
  3. Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
  4. This program can be distributed under the terms of the GNU LGPLv2.
  5. See the file COPYING.LIB.
  6. */
  7. #include "fuse_i.h"
  8. #include "fuse_misc.h"
  9. #include "fuse_lowlevel.h"
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <pthread.h>
  14. #include <assert.h>
  15. struct procdata {
  16. struct fuse *f;
  17. struct fuse_chan *prevch;
  18. struct fuse_session *prevse;
  19. fuse_processor_t proc;
  20. void *data;
  21. };
  22. static void mt_session_proc(void *data, const char *buf, size_t len,
  23. struct fuse_chan *ch)
  24. {
  25. struct procdata *pd = (struct procdata *) data;
  26. struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
  27. (void) len;
  28. (void) ch;
  29. pd->proc(pd->f, cmd, pd->data);
  30. }
  31. static void mt_session_exit(void *data, int val)
  32. {
  33. struct procdata *pd = (struct procdata *) data;
  34. if (val)
  35. fuse_session_exit(pd->prevse);
  36. else
  37. fuse_session_reset(pd->prevse);
  38. }
  39. static int mt_session_exited(void *data)
  40. {
  41. struct procdata *pd = (struct procdata *) data;
  42. return fuse_session_exited(pd->prevse);
  43. }
  44. static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
  45. {
  46. struct fuse_cmd *cmd;
  47. struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
  48. assert(size >= sizeof(cmd));
  49. cmd = fuse_read_cmd(pd->f);
  50. if (cmd == NULL)
  51. return 0;
  52. *(struct fuse_cmd **) buf = cmd;
  53. return sizeof(cmd);
  54. }
  55. int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
  56. {
  57. int res;
  58. struct procdata pd;
  59. struct fuse_session *prevse = fuse_get_session(f);
  60. struct fuse_session *se;
  61. struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
  62. struct fuse_chan *ch;
  63. struct fuse_session_ops sop = {
  64. .exit = mt_session_exit,
  65. .exited = mt_session_exited,
  66. .process = mt_session_proc,
  67. };
  68. struct fuse_chan_ops cop = {
  69. .receive = mt_chan_receive,
  70. };
  71. pd.f = f;
  72. pd.prevch = prevch;
  73. pd.prevse = prevse;
  74. pd.proc = proc;
  75. pd.data = data;
  76. se = fuse_session_new(&sop, &pd);
  77. if (se == NULL)
  78. return -1;
  79. ch = fuse_chan_new(&cop, fuse_chan_fd(prevch),
  80. sizeof(struct fuse_cmd *), &pd);
  81. if (ch == NULL) {
  82. fuse_session_destroy(se);
  83. return -1;
  84. }
  85. fuse_session_add_chan(se, ch);
  86. res = fuse_session_loop_mt(se);
  87. fuse_session_destroy(se);
  88. return res;
  89. }
  90. int fuse_loop_mt(struct fuse *f)
  91. {
  92. if (f == NULL)
  93. return -1;
  94. int res = fuse_start_cleanup_thread(f);
  95. if (res)
  96. return -1;
  97. res = fuse_session_loop_mt(fuse_get_session(f));
  98. fuse_stop_cleanup_thread(f);
  99. return res;
  100. }
  101. FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@");