SF: call the timer's callback in case of an error
Bug: 210065990
Test: new SF unit test
Change-Id: I4ae70e82e9402fc7d7eecc1a17c1b992eb3efab6
diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp
index 22c3a70..68f9321 100644
--- a/services/surfaceflinger/Scheduler/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/Timer.cpp
@@ -51,13 +51,25 @@
}
void Timer::reset() {
- cleanup();
- mTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
- mEpollFd = epoll_create1(EPOLL_CLOEXEC);
- if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
- ALOGE("could not create TimerDispatch mPipes");
- return;
- };
+ std::function<void()> cb;
+ {
+ std::lock_guard lock(mMutex);
+ if (mExpectingCallback && mCallback) {
+ cb = mCallback;
+ }
+
+ cleanup();
+ mTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+ mEpollFd = epoll_create1(EPOLL_CLOEXEC);
+ if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
+ ALOGE("could not create TimerDispatch mPipes");
+ }
+ }
+ if (cb) {
+ setDebugState(DebugState::InCallback);
+ cb();
+ setDebugState(DebugState::Running);
+ }
setDebugState(DebugState::Reset);
}
@@ -81,6 +93,8 @@
close(mPipes[kWritePipe]);
mPipes[kWritePipe] = -1;
}
+ mExpectingCallback = false;
+ mCallback = {};
}
void Timer::endDispatch() {
@@ -99,6 +113,7 @@
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
mCallback = cb;
+ mExpectingCallback = true;
struct itimerspec old_timer;
struct itimerspec new_timer {
@@ -198,6 +213,7 @@
{
std::lock_guard lock(mMutex);
cb = mCallback;
+ mExpectingCallback = false;
}
if (cb) {
setDebugState(DebugState::InCallback);
diff --git a/services/surfaceflinger/Scheduler/Timer.h b/services/surfaceflinger/Scheduler/Timer.h
index 628d800..eb65954 100644
--- a/services/surfaceflinger/Scheduler/Timer.h
+++ b/services/surfaceflinger/Scheduler/Timer.h
@@ -36,6 +36,10 @@
void alarmCancel() final;
void dump(std::string& result) const final;
+protected:
+ // For unit testing
+ int mEpollFd = -1;
+
private:
enum class DebugState {
Reset,
@@ -48,12 +52,12 @@
ftl_last = Terminated
};
- void reset();
- void cleanup();
+ void reset() EXCLUDES(mMutex);
+ void cleanup() REQUIRES(mMutex);
void setDebugState(DebugState state) EXCLUDES(mMutex);
int mTimerFd = -1;
- int mEpollFd = -1;
+
std::array<int, 2> mPipes = {-1, -1};
std::thread mDispatchThread;
@@ -63,6 +67,7 @@
mutable std::mutex mMutex;
std::function<void()> mCallback GUARDED_BY(mMutex);
+ bool mExpectingCallback GUARDED_BY(mMutex) = false;
DebugState mDebugState GUARDED_BY(mMutex);
};