summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
diff options
context:
space:
mode:
authorDominik Laskowski <domlaskowski@google.com>2019-02-01 16:47:58 -0800
committerDominik Laskowski <domlaskowski@google.com>2019-02-06 15:56:41 -0800
commitccf37d7447b6ced5f08955e8d75b9c992052bf98 (patch)
treef591310d70f18d6b019db59d8ba81c3553cd9006 /services/surfaceflinger/tests/unittests/EventThreadTest.cpp
parent846c8337f0d48ce794cc745c92449ce97fcb1bc7 (diff)
SF: Fix thread safety for scheduler callbacks
SurfaceFlinger::setRefreshRateTo, called from the Scheduler callbacks, reads HWC and SF state without locking mStateLock, concurrently with writes from the main thread. This CL registers ResetIdleTimerCallback per EventThreadConnection, and locks mStateLock for connections used off the main thread. Note that ExpiredTimerCallback locks mStateLock unconditionally, since it is always called from the IdleTimer thread. This CL also adds a thread annotation to setRefreshRateTo, and refactors it accordingly. Bug: 123715322 Test: libsurfaceflinger_unittest Test: Boot with scheduler enabled Change-Id: Id62c48ae22da38f292ffc18e8731a1c49a0a083c
Diffstat (limited to 'services/surfaceflinger/tests/unittests/EventThreadTest.cpp')
-rw-r--r--services/surfaceflinger/tests/unittests/EventThreadTest.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index ad7dcb4217..2be4fd078e 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -53,8 +53,10 @@ protected:
class MockEventThreadConnection : public EventThreadConnection {
public:
MockEventThreadConnection(android::impl::EventThread* eventThread,
- ResyncCallback&& resyncCallback)
- : EventThreadConnection(eventThread, std::move(resyncCallback)) {}
+ ResyncCallback&& resyncCallback,
+ ResetIdleTimerCallback&& resetIdleTimerCallback)
+ : EventThreadConnection(eventThread, std::move(resyncCallback),
+ std::move(resetIdleTimerCallback)) {}
MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
};
@@ -82,6 +84,7 @@ protected:
AsyncCallRecorder<void (*)(VSyncSource::Callback*)> mVSyncSetCallbackCallRecorder;
AsyncCallRecorder<void (*)(nsecs_t)> mVSyncSetPhaseOffsetCallRecorder;
AsyncCallRecorder<void (*)()> mResyncCallRecorder;
+ AsyncCallRecorder<void (*)()> mResetIdleTimerCallRecorder;
AsyncCallRecorder<void (*)(nsecs_t)> mInterceptVSyncCallRecorder;
ConnectionEventRecorder mConnectionEventCallRecorder{0};
@@ -136,7 +139,8 @@ void EventThreadTest::createThread() {
sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
ConnectionEventRecorder& recorder) {
sp<MockEventThreadConnection> connection =
- new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable());
+ new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable(),
+ mResetIdleTimerCallRecorder.getInvocable());
EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
return connection;
}
@@ -207,6 +211,7 @@ TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) {
EXPECT_FALSE(mVSyncSetCallbackCallRecorder.waitForCall(0us).has_value());
EXPECT_FALSE(mVSyncSetPhaseOffsetCallRecorder.waitForCall(0us).has_value());
EXPECT_FALSE(mResyncCallRecorder.waitForCall(0us).has_value());
+ EXPECT_FALSE(mResetIdleTimerCallRecorder.waitForCall(0us).has_value());
EXPECT_FALSE(mInterceptVSyncCallRecorder.waitForCall(0us).has_value());
EXPECT_FALSE(mConnectionEventCallRecorder.waitForCall(0us).has_value());
}
@@ -224,9 +229,10 @@ TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) {
TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) {
// Signal that we want the next vsync event to be posted to the connection
- mThread->requestNextVsync(mConnection, false);
+ mThread->requestNextVsync(mConnection, true);
- // EventThread should immediately request a resync.
+ // EventThread should immediately reset the idle timer and request a resync.
+ EXPECT_TRUE(mResetIdleTimerCallRecorder.waitForCall().has_value());
EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
// EventThread should enable vsync callbacks.