Loading core/java/android/os/CombinedMessageQueue/MessageQueue.java +25 −6 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public final class MessageQueue { @UnsupportedAppUsage private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; private boolean mQuitting; Loading Loading @@ -584,6 +585,16 @@ public final class MessageQueue { setFileDescriptorEvents(fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading Loading @@ -853,9 +864,18 @@ public final class MessageQueue { } } private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords || getQuitting()) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } private Message nextConcurrent() { final long ptr = mPtr; if (ptr == 0) { if (mPtr == 0) { return null; } Loading @@ -867,7 +887,7 @@ public final class MessageQueue { } mMessageDirectlyQueued = false; nativePollOnce(ptr, mNextPollTimeoutMillis); maybePollOnce(mNextPollTimeoutMillis); Message msg = nextMessage(false, false); if (msg != null) { Loading Loading @@ -934,8 +954,7 @@ public final class MessageQueue { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. final long ptr = mPtr; if (ptr == 0) { if (mPtr == 0) { return null; } Loading @@ -946,7 +965,7 @@ public final class MessageQueue { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); maybePollOnce(nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. Loading core/java/android/os/ConcurrentMessageQueue/MessageQueue.java +22 −1 Original line number Diff line number Diff line Loading @@ -438,6 +438,7 @@ public final class MessageQueue { private final Object mFileDescriptorRecordsLock = new Object(); @GuardedBy("mFileDescriptorRecordsLock") private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; // The next barrier token. // Barriers are indicated by messages with a null target whose arg1 field carries the token. Loading Loading @@ -885,6 +886,16 @@ public final class MessageQueue { } } private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords || getQuitting()) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } Message next() { final long ptr = mPtr; if (ptr == 0) { Loading @@ -899,7 +910,7 @@ public final class MessageQueue { } mMessageDirectlyQueued = false; nativePollOnce(ptr, mNextPollTimeoutMillis); maybePollOnce(mNextPollTimeoutMillis); Message msg = nextMessage(false, false); if (msg != null) { Loading Loading @@ -1750,6 +1761,16 @@ public final class MessageQueue { mFileDescriptorRecords.removeAt(index); setFileDescriptorEvents(fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading core/java/android/os/LegacyMessageQueue/MessageQueue.java +22 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public final class MessageQueue { @UnsupportedAppUsage private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; private boolean mQuitting; Loading Loading @@ -326,6 +327,16 @@ public final class MessageQueue { mFileDescriptorRecords.removeAt(index); nativeSetFileDescriptorEvents(mPtr, fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading Loading @@ -380,6 +391,16 @@ public final class MessageQueue { private static final AtomicLong mMessagesDelivered = new AtomicLong(); private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } @UnsupportedAppUsage Message next() { // Return here if the message loop has already quit and been disposed. Loading @@ -397,7 +418,7 @@ public final class MessageQueue { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); maybePollOnce(nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. Loading core/java/android/os/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,14 @@ flag { is_exported: true } flag { name: "message_queue_native_poll_once_and_for_all" namespace: "system_performance" description: "Don't call nativePollOnce unnecessarily." bug: "410218466" is_fixed_read_only: false } flag { name: "message_queue_testability" namespace: "system_performance" Loading Loading
core/java/android/os/CombinedMessageQueue/MessageQueue.java +25 −6 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public final class MessageQueue { @UnsupportedAppUsage private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; private boolean mQuitting; Loading Loading @@ -584,6 +585,16 @@ public final class MessageQueue { setFileDescriptorEvents(fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading Loading @@ -853,9 +864,18 @@ public final class MessageQueue { } } private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords || getQuitting()) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } private Message nextConcurrent() { final long ptr = mPtr; if (ptr == 0) { if (mPtr == 0) { return null; } Loading @@ -867,7 +887,7 @@ public final class MessageQueue { } mMessageDirectlyQueued = false; nativePollOnce(ptr, mNextPollTimeoutMillis); maybePollOnce(mNextPollTimeoutMillis); Message msg = nextMessage(false, false); if (msg != null) { Loading Loading @@ -934,8 +954,7 @@ public final class MessageQueue { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. final long ptr = mPtr; if (ptr == 0) { if (mPtr == 0) { return null; } Loading @@ -946,7 +965,7 @@ public final class MessageQueue { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); maybePollOnce(nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. Loading
core/java/android/os/ConcurrentMessageQueue/MessageQueue.java +22 −1 Original line number Diff line number Diff line Loading @@ -438,6 +438,7 @@ public final class MessageQueue { private final Object mFileDescriptorRecordsLock = new Object(); @GuardedBy("mFileDescriptorRecordsLock") private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; // The next barrier token. // Barriers are indicated by messages with a null target whose arg1 field carries the token. Loading Loading @@ -885,6 +886,16 @@ public final class MessageQueue { } } private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords || getQuitting()) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } Message next() { final long ptr = mPtr; if (ptr == 0) { Loading @@ -899,7 +910,7 @@ public final class MessageQueue { } mMessageDirectlyQueued = false; nativePollOnce(ptr, mNextPollTimeoutMillis); maybePollOnce(mNextPollTimeoutMillis); Message msg = nextMessage(false, false); if (msg != null) { Loading Loading @@ -1750,6 +1761,16 @@ public final class MessageQueue { mFileDescriptorRecords.removeAt(index); setFileDescriptorEvents(fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading
core/java/android/os/LegacyMessageQueue/MessageQueue.java +22 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public final class MessageQueue { @UnsupportedAppUsage private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private volatile boolean mHasFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; private boolean mQuitting; Loading Loading @@ -326,6 +327,16 @@ public final class MessageQueue { mFileDescriptorRecords.removeAt(index); nativeSetFileDescriptorEvents(mPtr, fdNum, 0); } // Indicate to maybePollOnce() if we have file descriptor records that // need to be polled for events. // We write this volatile field here and read it from the worker thread. // Adding an FD on a client thread and polling for events on the worker thread are // inherently racy. If the worker thread skips polling because it thinks there are // no FDs to watch and there is a Message to handle, then the worker will still // poll for the same events the next time. Events won't be missed, they'll just be // interleaved with Message handling in undefined ways. mHasFileDescriptorRecords = mFileDescriptorRecords.size() > 0; } // Called from native code. Loading Loading @@ -380,6 +391,16 @@ public final class MessageQueue { private static final AtomicLong mMessagesDelivered = new AtomicLong(); private void maybePollOnce(int nextPollTimeoutMillis) { if (!Flags.messageQueueNativePollOnceAndForAll()) { // If nativePollOnce optimization is not in effect, poll unconditionally. nativePollOnce(mPtr, nextPollTimeoutMillis); } else if (nextPollTimeoutMillis != 0 || mHasFileDescriptorRecords) { // We need to wait for the next message, or we need to poll for file descriptor events. nativePollOnce(mPtr, nextPollTimeoutMillis); } } @UnsupportedAppUsage Message next() { // Return here if the message loop has already quit and been disposed. Loading @@ -397,7 +418,7 @@ public final class MessageQueue { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); maybePollOnce(nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. Loading
core/java/android/os/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,14 @@ flag { is_exported: true } flag { name: "message_queue_native_poll_once_and_for_all" namespace: "system_performance" description: "Don't call nativePollOnce unnecessarily." bug: "410218466" is_fixed_read_only: false } flag { name: "message_queue_testability" namespace: "system_performance" Loading