File indexing completed on 2025-01-19 08:22:20
0001 /* 0002 SPDX-FileCopyrightText: 2017 Maxim Golov <maxim.golov@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include <atomic> 0008 #include <errno.h> 0009 #include <pthread.h> 0010 #include <signal.h> 0011 #include <stdio.h> 0012 #include <stdlib.h> 0013 #include <unistd.h> 0014 0015 std::atomic<bool> g_exit(false); 0016 0017 void* run_signal_thread(void*) 0018 { 0019 // Unblock interesting signals for this thread only 0020 sigset_t mask; 0021 sigemptyset(&mask); 0022 sigaddset(&mask, SIGQUIT); 0023 sigaddset(&mask, SIGINT); 0024 sigaddset(&mask, SIGTERM); 0025 0026 if (sigprocmask(SIG_SETMASK, &mask, nullptr) < 0) { 0027 perror("failed to set signal mask"); 0028 abort(); 0029 } 0030 0031 timespec timeout; 0032 timeout.tv_sec = 0; 0033 timeout.tv_nsec = 100 * 1000 * 1000; 0034 0035 do { 0036 int sig = sigtimedwait(&mask, nullptr, &timeout); 0037 if (sig < 0) { 0038 if (errno == EINTR || errno == EAGAIN) { 0039 continue; 0040 } else { 0041 perror("signal wait failed"); 0042 abort(); 0043 } 0044 } else if (sig == SIGQUIT || sig == SIGINT || sig == SIGTERM) { 0045 g_exit = true; 0046 } 0047 } while (!g_exit); 0048 0049 return nullptr; 0050 } 0051 0052 int main() 0053 { 0054 pthread_t signal_thread; 0055 0056 // when tracked by heaptrack, this will initialize our background thread 0057 // without the signal mask set. thus this thread will handle the signal 0058 // and kill the whole application then 0059 char* p = new char[1000]; 0060 0061 // block all signals for this thread 0062 sigset_t mask; 0063 sigfillset(&mask); 0064 int ret = pthread_sigmask(SIG_SETMASK, &mask, nullptr); 0065 if (ret < 0) { 0066 perror("failed to block signals"); 0067 abort(); 0068 } 0069 0070 ret = pthread_create(&signal_thread, nullptr, &run_signal_thread, nullptr); 0071 if (ret < 0) { 0072 perror("failed to create signal handler thread"); 0073 abort(); 0074 } 0075 0076 fprintf(stderr, "Started, press Ctrl-C to abort\n"); 0077 0078 // main loop 0079 while (!g_exit) { 0080 usleep(1000 * 1000); 0081 } 0082 0083 fprintf(stderr, "Interrupted\n"); 0084 0085 ret = pthread_join(signal_thread, nullptr); 0086 if (ret < 0) { 0087 perror("failed to join the signal handler thread"); 0088 abort(); 0089 } 0090 0091 delete[] p; 0092 0093 fprintf(stderr, "Done.\n"); 0094 0095 return 0; 0096 }