server: Change to register signal handler with glib 19/290819/10 accepted/tizen/unified/20230406.165729
authorTaeminYeom <taemin.yeom@samsung.com>
Tue, 4 Apr 2023 01:09:36 +0000 (10:09 +0900)
committerTaeminYeom <taemin.yeom@samsung.com>
Wed, 5 Apr 2023 05:28:27 +0000 (14:28 +0900)
Using std signal handler can make deadlock in terminating progress.
When std signal handler is called dispatching g_main_context,
glib attempts to lock g_main_context again.
To prevent this situation, it is needed to use glib signal handler function.

When there is a deadlock, the callstack is with below.

0  0x0000007fb3fa3860 in syscall () at ../sysdeps/unix/sysv/linux/aarch64/syscall.S:38
1  0x0000007fb44ced7c in g_mutex_lock_slowpath (mutex=0x55cda9eaa0) at ../glib/gthread-posix.c:1340
2  0x0000007fb44cf7a0 in g_mutex_lock (mutex=<optimized out>) at ../glib/gthread-posix.c:1364
3  0x0000007fb4480400 in g_main_loop_quit (loop=0x55cda9cc30) at ../glib/gmain.c:4136
4  0x0000007fb4286e68 in ipc::event_loop::terminate() (this=0x558f0e55b0 <sensor::server::m_loop>)
    at /usr/src/debug/sensord-4.0.54-1.aarch64/src/shared/event_loop.cpp:339
5  0x0000007fb4286f38 in ipc::event_loop::stop() (this=<optimized out>)
    at /usr/src/debug/sensord-4.0.54-1.aarch64/src/shared/event_loop.cpp:331
6  0x000000558f0c8620 in sensor::server::stop() ()
    at /usr/src/debug/sensord-4.0.54-1.aarch64/src/server/server.cpp:73
7  0x0000007fb48195b4 in <signal handler called> ()
8  0x0000007fb404fd64 in read () at /lib64/libpthread.so.0
9  0x0000007fb44caf90 in read (__nbytes=16, __buf=0x7fc1419d38, __fd=<optimized out>)
    at /usr/include/bits/unistd.h:44
10 0x0000007fb44caf90 in g_wakeup_acknowledge (wakeup=0x55cda89530) at ../glib/gwakeup.c:210
11 0x0000007fb447fa04 in g_main_context_check
    (context=context@entry=0x55cda9eaa0, max_priority=2147483647, fds=fds@entry=0x55cdb19e00, n_fds=n_fds@entry=27) at ../glib/gmain.c:3695
12 0x0000007fb447fe4c in g_main_context_iterate
    (context=0x55cda9eaa0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
    at ../glib/gmain.c:3914
13 0x0000007fb4480308 in g_main_loop_run (loop=0x55cda9cc30) at ../glib/gmain.c:4111
14 0x0000007fb4288308 in ipc::event_loop::run(int)
    (this=0x558f0e55b0 <sensor::server::m_loop>, timeout=<optimized out>)
    at /usr/src/debug/sensord-4.0.54-1.aarch64/src/shared/event_loop.cpp:322
15 0x000000558f0b6b50 in main(int, char**) (argc=<optimized out>, argv=<optimized out>)

Change-Id: I19e688ea16ab5e33b0c499abad866970a3d79761
Signed-off-by: TaeminYeom <taemin.yeom@samsung.com>
src/server/main.cpp

index 2f0357f0ec073bdd2d188043fb4816c71a8befcd..c4ec0488a0fad5fea0e60eef4e0b1bfc04dcc4e8 100644 (file)
  *
  */
 
-#include <sensor_log.h>
 #include <new>
 #include <csignal>
 
+#include <glib-unix.h>
+
+#include <sensor_log.h>
 #include "server.h"
 
 #define NEW_FAIL_LIMIT 3
 
 using namespace sensor;
 
-static void on_signal(int signum)
+static void handle_signal_std(int signum)
 {
        _W("Received SIGNAL(%d : %s)", signum, strsignal(signum));
+
+       /* raise SIGTERM manually to call handle_signal with glib dispatcher */
+       raise(SIGTERM);
+}
+
+static gboolean handle_signal(gpointer data)
+{
+       long signum = (long) data;
+       _W("Received SIGNAL(%ld : %s)", signum, strsignal(signum));
+
        server::stop();
+
+       return G_SOURCE_REMOVE;
 }
 
 static void on_new_failed(void)
@@ -48,11 +62,15 @@ static void on_new_failed(void)
 int main(int argc, char *argv[])
 {
        _I("Started");
-       std::signal(SIGINT, on_signal);
-       std::signal(SIGHUP, on_signal);
-       std::signal(SIGTERM, on_signal);
-       std::signal(SIGQUIT, on_signal);
-       std::signal(SIGABRT, on_signal);
+
+       /* register signal handler with glib to prevent deadlock */
+       g_unix_signal_add(SIGINT, handle_signal, (gpointer) SIGINT);
+       g_unix_signal_add(SIGHUP, handle_signal, (gpointer) SIGHUP);
+       g_unix_signal_add(SIGTERM, handle_signal, (gpointer) SIGTERM);
+
+       /* register signal handler with std for not supported signal in glib */
+       std::signal(SIGQUIT, handle_signal_std);
+       std::signal(SIGABRT, handle_signal_std);
        std::signal(SIGCHLD, SIG_IGN);
        std::signal(SIGPIPE, SIG_IGN);