Shutting down a managed runtime is not easy, see
for a discussion of how the MS.NET runtime does it. Basically, we could just
call libc exit () and be done with it, but people expect finalizers to be called
etc. Some people even expect us to clean up all memory used by the runtime.
Since cleaning up runtime memory structures while some threads are running which use them is not wise, we need to (at least) suspend all managed threads.
suspending threads is again not easy, since unix has no SuspendThread call like
win32 does, if a thread is suspended while holding some lock, the whole stuff
could deadlock. So this is not a simple problem at all, and I'm not suprised that
there are bugs. Also, as I said, f-spot is not a simple program, so it might
itself hang even when the runtime shutdown code works fine.
For a quick-and-dirty solution, you could try patching f-spot so instead of
calling Environment.Exit (), it would pinvoke the libc exit () function. That
would most likely work, except when some library like gtk installs an atexit ()
handler which does some strange thing and crashes/hangs...