aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/Host/common/MainLoop.cpp10
-rw-r--r--source/Host/openbsd/Host.cpp3
-rw-r--r--unittests/Host/MainLoopTest.cpp24
3 files changed, 33 insertions, 4 deletions
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 39c353e6717e..337ddd51dd6b 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -108,8 +108,14 @@ Status MainLoop::RunImpl::Poll() {
num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
out_events, llvm::array_lengthof(out_events), nullptr);
- if (num_events < 0)
- return Status("kevent() failed with error %d\n", num_events);
+ if (num_events < 0) {
+ if (errno == EINTR) {
+ // in case of EINTR, let the main loop run one iteration
+ // we need to zero num_events to avoid assertions failing
+ num_events = 0;
+ } else
+ return Status(errno, eErrorTypePOSIX);
+ }
return Status();
}
diff --git a/source/Host/openbsd/Host.cpp b/source/Host/openbsd/Host.cpp
index cba1f4ee6b7c..8db0498d14b5 100644
--- a/source/Host/openbsd/Host.cpp
+++ b/source/Host/openbsd/Host.cpp
@@ -68,8 +68,7 @@ GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(
diff --git a/unittests/Host/MainLoopTest.cpp b/unittests/Host/MainLoopTest.cpp
index 8f2c55c2416d..6b7a5cf1f55d 100644
--- a/unittests/Host/MainLoopTest.cpp
+++ b/unittests/Host/MainLoopTest.cpp
@@ -137,4 +137,28 @@ TEST_F(MainLoopTest, Signal) {
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);
}
+
+// Test that a signal which is not monitored by the MainLoop does not
+// cause a premature exit.
+TEST_F(MainLoopTest, UnmonitoredSignal) {
+ MainLoop loop;
+ Status error;
+ struct sigaction sa;
+ sa.sa_sigaction = [](int, siginfo_t *, void *) { };
+ sa.sa_flags = SA_SIGINFO; // important: no SA_RESTART
+ sigemptyset(&sa.sa_mask);
+ ASSERT_EQ(0, sigaction(SIGUSR2, &sa, nullptr));
+
+ auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error);
+ ASSERT_TRUE(error.Success());
+ std::thread killer([]() {
+ sleep(1);
+ kill(getpid(), SIGUSR2);
+ sleep(1);
+ kill(getpid(), SIGUSR1);
+ });
+ ASSERT_TRUE(loop.Run().Success());
+ killer.join();
+ ASSERT_EQ(1u, callback_count);
+}
#endif