Hello, when trackerd receives some signals, signal_handler() is called then do_cleanup() and exit(). If you add some sleep() in do_cleanup() you will see that all the threads stop at signals trapping! So, now, I propose to use SA_NODEFER as flag for sigaction() so other threads will continue to run. But there are still remaining issues. To synchronize threads in do_cleanup() some lock_mutex() are called on mutexes placed in while-loops. What I dislike there is that those threads will never reach their end: process_files_thread() will never call mysql_close() and mysql_thread_end() for instance... So I decided to make some threads (file_process_thread and file_metadata_thread) joinable and to wait their end with g_thread_join() after "is_running" was set to FALSE in do_cleanup(). process_user_request_queue_thread() function has a pathological problem: it uses g_async_queue_pop() which is blocked until a request come... So impossible to end this thread correctly. A "DBUS_SHUTDOWN" action may end this thread properly or we could play with _try_pop(), mutexes and g_usleep() like in the other functions... If we use a system with "stop" events in queues, we could use the same trick for process_files_thread() since it uses g_async_queue_try_pop() (that doesn't block) but get data from tracker-inotify.c (for instance). Currently inotify events are never stopped but we could stop them then put a "stop" in file_process_queue to end process_files_thread(). To resume this patch: less mutexes, _some_ threads that properly end but still some work to be done. Bonus: - I replaced exit(1) by exit(EXIT_FAILURE), and exit(0) by exit(EXIT_SUCCESS); - '#include "tracker-db.h"' was lose with #ifdef; - IMHO code after g_main_loop_run(loop) in main() will never be reached due to signal trapping, so I updated code according to that (see end of main() and do_cleanup()). Laurent.
Attachment:
better-signals-handling-patch.diff
Description: Text Data