From a665ca805c7ecda89ef95658f4d1c09ba6bd7f2e Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 8 Sep 2010 11:49:43 -0700 Subject: Input dispatcher ANR handling enhancements. This change is essentially a rewrite of the main input dispatcher loop with the target identification folded in. Since the input dispatcher now has all of the window state, it can make better decisions about when to ANR. Added a .5 second deadline for processing app switch keys. This behavior predates Gingerbread but had not previously been ported. Fixed some timing inaccuracies in the ANR accounting that could cause applications to ANR sooner than they should have. Added a mechanism for tracking key and motion events that have been dispatched to a window so that appropriate cancelation events can be synthesized when recovering from ANR. This change helps to keep applications in sync so they don't end up with stuck buttons upon recovery from ANRs. Added more comments to describe the tricky parts of PollLoop. Change-Id: I13dffca27acb436fc383980db536abc4d8b9e6f1 --- include/utils/PollLoop.h | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'include/utils/PollLoop.h') diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h index bc616ebc7d..c2dfe5da6e 100644 --- a/include/utils/PollLoop.h +++ b/include/utils/PollLoop.h @@ -172,22 +172,36 @@ private: void* data; }; - const bool mAllowNonCallbacks; - + const bool mAllowNonCallbacks; // immutable + + int mWakeReadPipeFd; // immutable + int mWakeWritePipeFd; // immutable + + // The lock guards state used to track whether there is a poll() in progress and whether + // there are any other threads waiting in wakeAndLock(). The condition variables + // are used to transfer control among these threads such that all waiters are + // serviced before a new poll can begin. + // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake + // until mPolling becomes false, then decrements mWaiters again. + // The poll() method blocks on mResume until mWaiters becomes 0, then sets + // mPolling to true, blocks until the poll completes, then resets mPolling to false + // and signals mResume if there are waiters. Mutex mLock; - bool mPolling; - uint32_t mWaiters; - Condition mAwake; - Condition mResume; - - int mWakeReadPipeFd; - int mWakeWritePipeFd; - + bool mPolling; // guarded by mLock + uint32_t mWaiters; // guarded by mLock + Condition mAwake; // guarded by mLock + Condition mResume; // guarded by mLock + + // The next two vectors are only mutated when mPolling is false since they must + // not be changed while the poll() system call is in progress. To mutate these + // vectors, the poll() must first be awoken then the lock acquired. Vector mRequestedFds; Vector mRequestedCallbacks; - Vector mPendingCallbacks; // used privately by pollOnce - Vector mPendingFds; // used privately by pollOnce + // This state is only used privately by pollOnce and does not require a lock since + // it runs on a single thread. + Vector mPendingCallbacks; + Vector mPendingFds; size_t mPendingFdsPos; void openWakePipe(); -- cgit v1.2.3-59-g8ed1b