diff options
| author | Jeff Brown <jeffbrown@google.com> | 2010-10-05 15:35:37 -0700 |
|---|---|---|
| committer | Jeff Brown <jeffbrown@google.com> | 2010-10-07 13:26:39 -0700 |
| commit | 415d8c38199e258dfce92cdb0c69e056b3b51ef8 (patch) | |
| tree | 5bf6d167a19b272f2a153df6010a7dd6f58a274f /core/java/android/os/MessageQueue.java | |
| parent | 930d6c3cd5ad387489eb1d35a38beeafe54166b6 (diff) | |
Switch Looper back to using poll() instead of epoll().
Added a couple of micro-optimizations to avoid calling wake() unnecessarily
and reduce JNI overhead slightly.
Fixed a minor issue where we were not clearing the "next" field of Messages
returned by the MessageQueue so the Message would hold on to its successor
and potentially prevent the GC from collecting it if the message were leaked
somehow.
Change-Id: I488d29417ce0cdd7d0e447cda76ec978ef7f811c
Diffstat (limited to 'core/java/android/os/MessageQueue.java')
| -rw-r--r-- | core/java/android/os/MessageQueue.java | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 6237c0e4e523..009017753ed3 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; } |
