Add new Looper API to check whether the looper is idle.

This is just to support the watchdog to give it a faster
way to determine if a thread is deadlocked without having
to post a message to it.

Change-Id: I068dc8b9387caf94fe5811fb4aeb0f9b57b1a080
This commit is contained in:
Dianne Hackborn 2013-05-06 14:25:20 -07:00
parent 779434378e
commit ffad7d1fdc
2 changed files with 23 additions and 0 deletions

View File

@ -296,6 +296,13 @@ public:
*/
void removeMessages(const sp<MessageHandler>& handler, int what);
/**
* Return whether this looper's thread is currently idling -- that is, whether it
* stopped waiting for more work to do. Note that this is intrinsically racy, since
* its state can change before you get the result back.
*/
bool isIdling() const;
/**
* Prepares a looper associated with the calling thread, and returns it.
* If the thread already has a looper, it is returned. Otherwise, a new
@ -353,6 +360,10 @@ private:
Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
bool mSendingMessage; // guarded by mLock
// Whether we are currently waiting for work. Not protected by a lock,
// any use of it is racy anyway.
volatile bool mIdling;
int mEpollFd; // immutable
// Locked list of file descriptor monitoring requests.

View File

@ -84,6 +84,8 @@ Looper::Looper(bool allowNonCallbacks) :
LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
errno);
mIdling = false;
// Allocate the epoll instance and register the wake pipe.
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
@ -214,9 +216,15 @@ int Looper::pollInner(int timeoutMillis) {
mResponses.clear();
mResponseIndex = 0;
// We are about to idle.
mIdling = true;
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
// No longer idling.
mIdling = false;
// Acquire lock.
mLock.lock();
@ -558,4 +566,8 @@ void Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
} // release lock
}
bool Looper::isIdling() const {
return mIdling;
}
} // namespace android