Author: mgorny
Date: Fri Feb 15 04:13:02 2019
New Revision: 354122

URL: http://llvm.org/viewvc/llvm-project?rev=354122&view=rev
Log:
[lldb] [MainLoop] Add kevent() EINTR handling

Add missing EINTR handling for kevent() calls.  If the call is
interrupted, return from Poll() as if zero events were returned and let
the polling resume on next iteration.  This fixes test flakiness
on NetBSD.

Includes a test case suggested by Pavel Labath on D42206.

Differential Revision: https://reviews.llvm.org/D58230

Modified:
    lldb/trunk/source/Host/common/MainLoop.cpp
    lldb/trunk/unittests/Host/MainLoopTest.cpp

Modified: lldb/trunk/source/Host/common/MainLoop.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/MainLoop.cpp?rev=354122&r1=354121&r2=354122&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/MainLoop.cpp (original)
+++ lldb/trunk/source/Host/common/MainLoop.cpp Fri Feb 15 04:13:02 2019
@@ -107,8 +107,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(errno, eErrorTypePOSIX);
+  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();
 }
 

Modified: lldb/trunk/unittests/Host/MainLoopTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/MainLoopTest.cpp?rev=354122&r1=354121&r2=354122&view=diff
==============================================================================
--- lldb/trunk/unittests/Host/MainLoopTest.cpp (original)
+++ lldb/trunk/unittests/Host/MainLoopTest.cpp Fri Feb 15 04:13:02 2019
@@ -141,4 +141,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


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to