diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/os/MessageQueue.java | 21 | ||||
-rw-r--r-- | core/jni/android_os_MessageQueue.cpp | 32 |
2 files changed, 27 insertions, 26 deletions
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 6237c0e..0090177 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -34,16 +34,19 @@ public class MessageQueue { Message mMessages; private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private IdleHandler[] mPendingIdleHandlers; - private boolean mQuiting = false; + private boolean mQuiting; boolean mQuitAllowed = true; + // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. + private boolean mBlocked; + @SuppressWarnings("unused") private int mPtr; // used by native code private native void nativeInit(); private native void nativeDestroy(); - private native boolean nativePollOnce(int timeoutMillis); - private native void nativeWake(); + private native void nativePollOnce(int ptr, int timeoutMillis); + private native void nativeWake(int ptr); /** * Callback interface for discovering when a thread is going to block @@ -113,7 +116,7 @@ public class MessageQueue { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } - nativePollOnce(nextPollTimeoutMillis); + nativePollOnce(mPtr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. @@ -122,7 +125,9 @@ public class MessageQueue { if (msg != null) { final long when = msg.when; if (now >= when) { + mBlocked = false; mMessages = msg.next; + msg.next = null; if (Config.LOGV) Log.v("MessageQueue", "Returning message: " + msg); return msg; } else { @@ -138,6 +143,7 @@ public class MessageQueue { } if (pendingIdleHandlerCount == 0) { // No idle handlers to run. Loop and wait some more. + mBlocked = true; continue; } @@ -184,6 +190,7 @@ public class MessageQueue { if (msg.target == null && !mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit"); } + final boolean needWake; synchronized (this) { if (mQuiting) { RuntimeException e = new RuntimeException( @@ -200,6 +207,7 @@ public class MessageQueue { if (p == null || when == 0 || when < p.when) { msg.next = p; mMessages = msg; + needWake = mBlocked; // new head, might need to wake up } else { Message prev = null; while (p != null && p.when <= when) { @@ -208,9 +216,12 @@ public class MessageQueue { } msg.next = prev.next; prev.next = msg; + needWake = false; // still waiting on head, no need to wake up } } - nativeWake(); + if (needWake) { + nativeWake(mPtr); + } return true; } diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp index 1b203ca..d2e5462 100644 --- a/core/jni/android_os_MessageQueue.cpp +++ b/core/jni/android_os_MessageQueue.cpp @@ -41,7 +41,7 @@ public: inline sp<Looper> getLooper() { return mLooper; } - bool pollOnce(int timeoutMillis); + void pollOnce(int timeoutMillis); void wake(); private: @@ -61,8 +61,8 @@ NativeMessageQueue::NativeMessageQueue() { NativeMessageQueue::~NativeMessageQueue() { } -bool NativeMessageQueue::pollOnce(int timeoutMillis) { - return mLooper->pollOnce(timeoutMillis) != ALOOPER_POLL_TIMEOUT; +void NativeMessageQueue::pollOnce(int timeoutMillis) { + mLooper->pollOnce(timeoutMillis); } void NativeMessageQueue::wake() { @@ -112,24 +112,14 @@ static void throwQueueNotInitialized(JNIEnv* env) { jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized"); } -static jboolean android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, - jint timeoutMillis) { - NativeMessageQueue* nativeMessageQueue = - android_os_MessageQueue_getNativeMessageQueue(env, obj); - if (! nativeMessageQueue) { - throwQueueNotInitialized(env); - return false; - } - return nativeMessageQueue->pollOnce(timeoutMillis); +static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, + jint ptr, jint timeoutMillis) { + NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); + nativeMessageQueue->pollOnce(timeoutMillis); } -static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj) { - NativeMessageQueue* nativeMessageQueue = - android_os_MessageQueue_getNativeMessageQueue(env, obj); - if (! nativeMessageQueue) { - throwQueueNotInitialized(env); - return; - } +static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) { + NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); return nativeMessageQueue->wake(); } @@ -139,8 +129,8 @@ static JNINativeMethod gMessageQueueMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit }, { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy }, - { "nativePollOnce", "(I)Z", (void*)android_os_MessageQueue_nativePollOnce }, - { "nativeWake", "()V", (void*)android_os_MessageQueue_nativeWake } + { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce }, + { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake } }; #define FIND_CLASS(var, className) \ |