summaryrefslogtreecommitdiffstats
path: root/tests/signal_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/signal_test.cpp')
-rw-r--r--tests/signal_test.cpp101
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));
+}