aboutsummaryrefslogtreecommitdiffstats
path: root/tests/signal_test.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-02-21 11:22:23 -0800
committerElliott Hughes <enh@google.com>2013-02-21 11:22:23 -0800
commitfae89fc4042ee4c360842234dfda7831c313bd44 (patch)
treeaa35c41ee98aad9b065591a5497515163534e956 /tests/signal_test.cpp
parentccd403161cdcc88a0ffcaecd1bc707e2d4c88a1c (diff)
downloadandroid_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.tar.gz
android_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.tar.bz2
android_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.zip
Fix raise(3) so it works in signal handlers.
We could special-case raise(3) in non-threaded programs, but the more conservative course is to make pthread_kill(3) work in signal handlers at the cost of a race shared by other C libraries. Change-Id: I59fb23d03bdabf403435e731704b33acdf3e0234
Diffstat (limited to 'tests/signal_test.cpp')
-rw-r--r--tests/signal_test.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index b100372c9..e41dc1cb5 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -76,6 +76,25 @@ static void TestSigSet2(Fn fn) {
ASSERT_EQ(0, errno);
}
+class ScopedSignalHandler {
+ public:
+ ScopedSignalHandler(int signal_number, void (*handler)(int)) : signal_number_(signal_number) {
+ sigemptyset(&action_.sa_mask);
+ action_.sa_flags = 0;
+ action_.sa_handler = handler;
+ sigaction(signal_number_, &action_, &old_action_);
+ }
+
+ ~ScopedSignalHandler() {
+ sigaction(signal_number_, &old_action_, NULL);
+ }
+
+ private:
+ struct sigaction action_;
+ struct sigaction old_action_;
+ const int signal_number_;
+};
+
TEST(signal, sigismember_invalid) {
TestSigSet2(sigismember);
}
@@ -102,16 +121,25 @@ TEST(signal, raise_invalid) {
ASSERT_EQ(EINVAL, errno);
}
+static void raise_in_signal_handler_helper(int signal_number) {
+ ASSERT_EQ(SIGALRM, signal_number);
+ static int count = 0;
+ if (++count == 1) {
+ raise(SIGALRM);
+ }
+}
+
+TEST(signal, raise_in_signal_handler) {
+ ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper);
+ raise(SIGALRM);
+}
+
static void HandleSIGALRM(int signal_number) {
ASSERT_EQ(SIGALRM, signal_number);
}
TEST(signal, sigwait) {
- struct sigaction action;
- sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- action.sa_handler = HandleSIGALRM;
- sigaction(SIGALRM, &action, NULL);
+ ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM);
sigset_t wait_set;
sigemptyset(&wait_set);