thread state coordinator: added test for notify after two pending thread stops.

Glad I did - caught a bug where the auto variable was not a reference
to a set and instead was a copy.  I need to review rules on that!

llvm-svn: 218558
This commit is contained in:
Todd Fiala 2014-09-27 01:11:17 +00:00
parent 779c6f2573
commit 9dd7334d69
2 changed files with 62 additions and 1 deletions

View File

@ -111,6 +111,67 @@ TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenOnePendingStop)
ASSERT_EQ (TRIGGERING_TID, reported_firing_tid);
}
TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenTwoPendingStops)
{
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 };
bool call_after_fired = false;
lldb::tid_t reported_firing_tid = 0;
int request_thread_stop_calls = 0;
ThreadStateCoordinator::ThreadIDSet request_thread_stop_tids;
// 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_tids.insert (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 ());
// Now the request thread stops should have been called for the pending stop tids.
ASSERT_EQ (2, request_thread_stop_calls);
ASSERT_EQ (1, request_thread_stop_tids.count (PENDING_STOP_TID));
ASSERT_EQ (1, request_thread_stop_tids.count (PENDING_STOP_TID_02));
// 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);
// Report the that the first pending stop occurred.
coordinator.NotifyThreadStop (PENDING_STOP_TID);
ASSERT_EQ (true, coordinator.ProcessNextEvent ());
// Shouldn't take effect until after both pending threads are notified.
ASSERT_EQ (false, call_after_fired);
// Report the that the first pending stop occurred.
coordinator.NotifyThreadStop (PENDING_STOP_TID_02);
ASSERT_EQ (false, call_after_fired);
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);
}
TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenPendingAlreadyStopped)
{
ThreadStateCoordinator coordinator(NOPLogger);

View File

@ -255,7 +255,7 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid)
{
EventCallAfterThreadsStop *call_after_event = static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ());
auto remaining_stop_tids = call_after_event->GetRemainingWaitTIDs ();
ThreadIDSet &remaining_stop_tids = call_after_event->GetRemainingWaitTIDs ();
// Remove this tid if it was in it.
remaining_stop_tids.erase (tid);