diff options
Diffstat (limited to 'lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp')
| -rw-r--r-- | lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp b/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp index f83d99de402..b08c2c2e3a8 100644 --- a/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp +++ b/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp @@ -220,3 +220,118 @@ TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenPendingAlreadyStop ASSERT_EQ (true, call_after_fired); ASSERT_EQ (TRIGGERING_TID, reported_firing_tid); } + +TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenTwoPendingOneAlreadyStopped) +{ + ThreadStateCoordinator coordinator(NOPLogger); + + const lldb::tid_t TRIGGERING_TID = 4105; + const lldb::tid_t PENDING_STOP_TID = 3; + const lldb::tid_t PENDING_STOP_TID_02 = 29016; + + ThreadStateCoordinator::ThreadIDSet pending_stop_tids { PENDING_STOP_TID, PENDING_STOP_TID_02 }; + + // Tell coordinator the pending stop tid is already stopped. + coordinator.NotifyThreadStop (PENDING_STOP_TID); + ASSERT_EQ (true, coordinator.ProcessNextEvent ()); + + // Now fire the deferred thread stop notification, indicating that the pending thread + // must be stopped before we notify. + bool call_after_fired = false; + lldb::tid_t reported_firing_tid = 0; + + int request_thread_stop_calls = 0; + lldb::tid_t request_thread_stop_tid = 0; + + // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. + coordinator.CallAfterThreadsStop (TRIGGERING_TID, + pending_stop_tids, + [&](lldb::tid_t tid) { + ++request_thread_stop_calls; + request_thread_stop_tid = tid; + + }, + [&](lldb::tid_t tid) { + call_after_fired = true; + reported_firing_tid = tid; + }); + + // Neither trigger should have gone off yet. + ASSERT_EQ (false, call_after_fired); + ASSERT_EQ (0, request_thread_stop_calls); + + // Process next event. + ASSERT_EQ (true, coordinator.ProcessNextEvent ()); + + // The pending stop should only fire for one of the threads, the one that wasn't already stopped. + ASSERT_EQ (1, request_thread_stop_calls); + ASSERT_EQ (PENDING_STOP_TID_02, request_thread_stop_tid); + + // The deferred signal notification should not yet have fired since all pending thread stops have not yet occurred. + ASSERT_EQ (false, call_after_fired); + + // Notify final thread has stopped. + coordinator.NotifyThreadStop (PENDING_STOP_TID_02); + ASSERT_EQ (true, coordinator.ProcessNextEvent ()); + + // The deferred signal notification should have fired since all requirements were met. + ASSERT_EQ (true, call_after_fired); + ASSERT_EQ (TRIGGERING_TID, reported_firing_tid); +} + +TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenOnePendingThreadDies) +{ + ThreadStateCoordinator coordinator(NOPLogger); + + const lldb::tid_t TRIGGERING_TID = 4105; + const lldb::tid_t PENDING_STOP_TID = 3; + + ThreadStateCoordinator::ThreadIDSet pending_stop_tids { PENDING_STOP_TID }; + + bool call_after_fired = false; + lldb::tid_t reported_firing_tid = 0; + + bool request_thread_stop_called = false; + lldb::tid_t request_thread_stop_tid = 0; + + // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. + coordinator.CallAfterThreadsStop (TRIGGERING_TID, + pending_stop_tids, + [&](lldb::tid_t tid) { + request_thread_stop_called = true; + request_thread_stop_tid = tid; + + }, + [&](lldb::tid_t tid) { + call_after_fired = true; + reported_firing_tid = tid; + }); + + // Neither trigger should have gone off yet. + ASSERT_EQ (false, call_after_fired); + ASSERT_EQ (false, request_thread_stop_called); + + // Process next event. + ASSERT_EQ (true, coordinator.ProcessNextEvent ()); + + // Now the request thread stop should have been called for the pending stop. + ASSERT_EQ (true, request_thread_stop_called); + ASSERT_EQ (PENDING_STOP_TID, request_thread_stop_tid); + + // But we still shouldn't have the deferred signal call go off yet. Need to wait for the stop to be reported. + ASSERT_EQ (false, call_after_fired); + + // Now report the that the thread with pending stop dies. + coordinator.NotifyThreadDeath (PENDING_STOP_TID); + + // Shouldn't take effect until after next processing step. + ASSERT_EQ (false, call_after_fired); + + // Process next event. + ASSERT_EQ (true, coordinator.ProcessNextEvent ()); + + // Deferred signal notification should have fired now. + ASSERT_EQ (true, call_after_fired); + ASSERT_EQ (TRIGGERING_TID, reported_firing_tid); +} + |

