diff options
Diffstat (limited to 'tests/signal_test.cpp')
-rw-r--r-- | tests/signal_test.cpp | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp index 8fd8b72..f8fdc3f 100644 --- a/tests/signal_test.cpp +++ b/tests/signal_test.cpp @@ -16,9 +16,10 @@ #include <signal.h> -#include <errno.h> #include <gtest/gtest.h> +#include <errno.h> + #include "ScopedSignalHandler.h" static size_t SIGNAL_MIN() { @@ -276,3 +277,101 @@ TEST(signal, limits) { // We don't currently reserve any at the top. ASSERT_EQ(SIGRTMAX, __SIGRTMAX); } + +static int g_sigqueue_signal_handler_call_count = 0; + +static void SigqueueSignalHandler(int signum, siginfo_t* info, void*) { + ASSERT_EQ(SIGALRM, signum); + ASSERT_EQ(SIGALRM, info->si_signo); + ASSERT_EQ(SI_QUEUE, info->si_code); + ASSERT_EQ(1, info->si_value.sival_int); + ++g_sigqueue_signal_handler_call_count; +} + +TEST(signal, sigqueue) { + ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO); + sigval_t sigval; + sigval.sival_int = 1; + errno = 0; + ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); + ASSERT_EQ(0, errno); + ASSERT_EQ(1, g_sigqueue_signal_handler_call_count); +} + +TEST(signal, sigwaitinfo) { + // Block SIGALRM. + sigset_t just_SIGALRM; + sigemptyset(&just_SIGALRM); + sigaddset(&just_SIGALRM, SIGALRM); + sigset_t original_set; + ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); + + // Raise SIGALRM. + sigval_t sigval; + sigval.sival_int = 1; + ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); + + // Get pending SIGALRM. + siginfo_t info; + errno = 0; + ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info)); + ASSERT_EQ(0, errno); + ASSERT_EQ(SIGALRM, info.si_signo); + ASSERT_EQ(1, info.si_value.sival_int); + + ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); +} + +TEST(signal, sigtimedwait) { + // Block SIGALRM. + sigset_t just_SIGALRM; + sigemptyset(&just_SIGALRM); + sigaddset(&just_SIGALRM, SIGALRM); + sigset_t original_set; + ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); + + // Raise SIGALRM. + sigval_t sigval; + sigval.sival_int = 1; + ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); + + // Get pending SIGALRM. + siginfo_t info; + struct timespec timeout; + timeout.tv_sec = 2; + timeout.tv_nsec = 0; + errno = 0; + ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout)); + ASSERT_EQ(0, errno); + + ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); +} + +static int64_t NanoTime() { + struct timespec t; + t.tv_sec = t.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &t); + return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec; +} + +TEST(signal, sigtimedwait_timeout) { + // Block SIGALRM. + sigset_t just_SIGALRM; + sigemptyset(&just_SIGALRM); + sigaddset(&just_SIGALRM, SIGALRM); + sigset_t original_set; + ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); + + // Wait timeout. + int64_t start_time = NanoTime(); + siginfo_t info; + struct timespec timeout; + timeout.tv_sec = 0; + timeout.tv_nsec = 1000000; + errno = 0; + ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout)); + ASSERT_EQ(EAGAIN, errno); + ASSERT_GE(NanoTime() - start_time, 1000000); + + ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); +} |