From: Dianne Hackborn Date: Mon, 6 May 2013 21:25:20 +0000 (-0700) Subject: Add new Looper API to check whether the looper is idle. X-Git-Tag: android-x86-4.4-r1~258 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ffad7d1fdc8297df8285f16592f6f2ec3cab9828;p=android-x86%2Fframeworks-native.git 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 --- diff --git a/include/utils/Looper.h b/include/utils/Looper.h index d4a0067fde..2e0651a3c7 100644 --- a/include/utils/Looper.h +++ b/include/utils/Looper.h @@ -297,6 +297,13 @@ public: void removeMessages(const sp& 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 * one is created, associated with the thread, and returned. @@ -353,6 +360,10 @@ private: Vector 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. diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp index a5e66458c2..c51df2d1a8 100644 --- a/libs/utils/Looper.cpp +++ b/libs/utils/Looper.cpp @@ -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& handler, int what) { } // release lock } +bool Looper::isIdling() const { + return mIdling; +} + } // namespace android