File indexing completed on 2024-04-21 05:41:33

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 }