3

I'm developing a fuse filesystem and before calling fuse_main_real() I'm starting a std::thread in a class instance to do some background work.

this->t_receive = new std::thread([this] { this->receive(); });

However, it seems like fuse_main_real() kills this thread when going into background.
If I start the program with the -f option, which tells fuse to stay in the foreground, the problem does not occur and the thread survives.

I'm not sure what fuse does to go into background.

How do I make my thread survive being backgrounded?


Edit: Here's a basic example that exposes the problem:

#define FUSE_USE_VERSION 30

#include <iostream>
#include <thread>

#include <fuse.h>

static void thread_method()
{
        while (true)
        {
                std::cout << "test" << std::endl;
                std::this_thread::sleep_for(std::chrono::seconds(1));
        }
}

struct testop : fuse_operations
{ };

static struct testop ops;

int main(int argc, char** argv)
{
        std::thread(thread_method).detach();
        fuse_main_real(argc, argv, &ops, sizeof(fuse_operations), NULL);
}

Compile with

g++ -D_FILE_OFFSET_BITS=64 `pkg-config --cflags fuse` -lfuse -lpthread -std=c++14 -o test.o test.cpp

Command that works (repeatedly says "test"):

./test.o -f /home/test/testmountpoint

Command that doesn't work and shows the problem (says "test" once):

./test.o /home/test/testmountpoint
Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
  • 1
    That question seems incomplete... – Phil1970 Sep 26 '17 at 23:45
  • Unrelated: Why dynamically allocate a `thread`? Seems an odd and possibly reckless choice. – user4581301 Sep 26 '17 at 23:57
  • 1
    I'm guessing that fuse uses "fork and exit" to daemonize. This causes a new background process to be created, and the original main process to terminate, along with it's threads. Ideally you would create the thread you need in the child process after the fork has happened. Unfortunately I don't know enough about the internals of fuse to know how to do this. – clstrfsck Sep 27 '17 at 00:02
  • I think msandiford is right. Daemonization is usually done by fork-then-exit steps. Check if your thread is still alive in the child process. – Ben Sep 27 '17 at 00:10
  • @Phil1970 I've added an example. – Cobra_Fast Sep 27 '17 at 00:22
  • 1
    A little bit of googling suggests that you should create the thread in the `.init` function specified in `fuse_operations` passed to `fuse_main_real`. – clstrfsck Sep 27 '17 at 02:37

1 Answers1

2

The libfuse wiki says that

Miscellaneous threads should be started from the init() method. Threads started before fuse_main() will exit when the process goes into the background.

log0
  • 10,489
  • 4
  • 28
  • 62