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