summaryrefslogtreecommitdiffstats
path: root/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp')
-rw-r--r--lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp115
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);
+}
+
OpenPOWER on IntegriCloud