1+ use nix:: sys:: signal;
12use std:: env;
3+ use std:: thread;
4+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
25
36use crate :: global:: on_exit;
47use crate :: logger;
58use crate :: opt;
9+ use crate :: spin_lock:: SpinLock ;
610use crate :: utils:: generate_filename;
711
12+ static SIGNALWAIT_THREAD_HANDLE : SpinLock < Option < thread:: JoinHandle < ( ) > > > =
13+ SpinLock :: new ( None ) ;
14+
815fn initialize_logger ( ) {
916 static mut SYSCALL_LOGGER : logger:: SyscallLogger = logger:: SyscallLogger :: empty ( ) ;
1017 static mut FILE_LOGGER : logger:: FileLogger = logger:: FileLogger :: empty ( ) ;
@@ -55,33 +62,50 @@ fn initialize_atexit_hook() {
5562}
5663
5764fn initialize_signal_handlers ( ) {
58- extern "C" fn sigusr_handler ( signal : libc:: c_int ) {
59- let signal_name = match signal {
60- libc:: SIGUSR1 => "SIGUSR1" ,
61- libc:: SIGUSR2 => "SIGUSR2" ,
62- _ => "???" ,
63- } ;
64-
65- info ! (
66- "Signal handler triggered with signal: {} ({})" ,
67- signal_name, signal
68- ) ;
69- crate :: global:: toggle ( ) ;
65+ if !opt:: get ( ) . register_sigusr1 && !opt:: get ( ) . register_sigusr2 {
66+ info ! ( "Skip signal register." ) ;
67+ return ;
7068 }
71-
69+ let mut sigset = signal :: SigSet :: empty ( ) ;
7270 if opt:: get ( ) . register_sigusr1 {
71+ sigset. add ( signal:: Signal :: SIGUSR1 ) ;
7372 info ! ( "Registering SIGUSR1 handler..." ) ;
74- unsafe {
75- libc:: signal ( libc:: SIGUSR1 , sigusr_handler as libc:: sighandler_t ) ;
76- }
7773 }
78-
7974 if opt:: get ( ) . register_sigusr2 {
75+ sigset. add ( signal:: Signal :: SIGUSR2 ) ;
8076 info ! ( "Registering SIGUSR2 handler..." ) ;
81- unsafe {
82- libc:: signal ( libc:: SIGUSR2 , sigusr_handler as libc:: sighandler_t ) ;
83- }
8477 }
78+ sigset. thread_block ( ) . expect ( "Register signal failed!" ) ;
79+
80+ let mut thread_handle = SIGNALWAIT_THREAD_HANDLE . lock ( ) ;
81+ static SIG_THREAD_RUNNING : AtomicBool = AtomicBool :: new ( false ) ;
82+ let new_handle = thread:: Builder :: new ( )
83+ . name ( "Sigwait" . into ( ) )
84+ . spawn ( move || loop {
85+ match sigset. wait ( ) {
86+ Ok ( sig) => {
87+ let signal_name = match sig {
88+ signal:: Signal :: SIGUSR1 => "SIGUSR1" ,
89+ signal:: Signal :: SIGUSR2 => "SIGUSR2" ,
90+ _ => "???" ,
91+ } ;
92+
93+ info ! (
94+ "Signal handler triggered with signal: {} ({})" ,
95+ signal_name, sig
96+ ) ;
97+ crate :: global:: toggle ( ) ;
98+ }
99+ Err ( e) => error ! ( "Signal wait error: {}" , e) ,
100+ }
101+ } )
102+ . expect ( "Failed to start Sigwait thread" ) ;
103+
104+ while SIG_THREAD_RUNNING . load ( Ordering :: SeqCst ) == false {
105+ thread:: yield_now ( ) ;
106+ }
107+
108+ * thread_handle = Some ( new_handle) ;
85109}
86110
87111pub fn startup ( ) {
@@ -93,12 +117,13 @@ pub fn startup() {
93117 }
94118
95119 initialize_atexit_hook ( ) ;
120+
121+ initialize_signal_handlers ( ) ;
122+
96123 if !opt:: get ( ) . disabled_by_default {
97124 crate :: global:: toggle ( ) ;
98125 }
99126
100- initialize_signal_handlers ( ) ;
101-
102127 env:: remove_var ( "LD_PRELOAD" ) ;
103128 info ! ( "Startup initialization finished" ) ;
104129}
0 commit comments