|
From: Mike S. <ma...@gm...> - 2012-01-25 04:13:39
|
On Mon, Jan 23, 2012 at 11:31 AM, Miklos Szeredi <mi...@sz...> wrote:
> Andrew Tomazos <an...@to...> writes:
>
>> Hey all,
>>
>> So I figured out what was going on in my case anyway:
>>
>> Normally if a signal handler is executed while a system call (such as
>> read(2)) is blocking, the system call returns immediately (after the
>> signal handler is completed executing) with an EINTR. This is clearly
>> the behaviour that fuse_session_loop and fuse_session_exit were
>> designed for.
>>
>> However if the signal handler is installed with the SA_RESTART flag
>> set (see sigaction(2)) the system call will not return with EINTR
>> after the signal handler has executed. The system call will resume
>> blocking instead.
>>
>> For some reason on my system (Ubuntu 11.10 x86_64) the default
>> behaviour of signal(2) is to install the signal handler with the
>> SA_RESTART flag.
>
> Why do you need to install your own signal handler?
>
> As I've said, the cleanest way to do this is to use the default signal
> handlers provided by fuse and do your own cleanup after fuse_loop/_mt()
> or fuse_main(), whichever you are using.
>
> Thanks,
> Miklos
I was able to use the fuse signal handlers along with the latest
fuse_terminate() patch and it seems to work. However, I did have to
add some extra synchronization between my fuse thread and my main
thread. Essentially my fuse thread looks like:
fuse_thread:
fuse_loop()
kill(0, SIGINT) // propagate SIGINT in case the main process was
killed with SIGINT directly (which doesn't go to the process group)
get fuse lock
fuse_remove_signal_handlers()
fuse_unmount()
fuse_destroy()
fuse structure = NULL
release fuse lock
I need to call unmount in here because my main thread waits for all
the worker threads/processes that use the filesystem to return before
calling fuse_terminate(). If I send a signal, one of the threads may
get stuck trying to use the fuse fs, but since I've already broken out
of the loop the request will hang unless I unmount.
My main thread then does this:
main_thread:
wait for all worker threads/processes
get fuse lock
if(fuse structure)
fuse_terminate()
release fuse lock
join fuse thread
This allows me to cleanup if fuse catches a signal (in which case the
fuse structure is already NULL and doesn't need to terminate), or if
it exits cleanly I call terminate and then the fuse thread shuts down.
It was a bit tricky to get my head wrapped around but it seems to work
as designed now :)
Thanks,
-Mike
|