summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mark Fasheh <mfasheh@google.com> 2024-12-07 00:54:11 +0000
committer Mark Fasheh <mfasheh@google.com> 2024-12-10 00:54:42 +0000
commitc338cb3db9bd41c3a8e53f3bed33265eba0348cc (patch)
tree13a017248d5d67da35eaab15955960ec483b7cbd
parent09429c7d24cc423d4fe99dad6fe2c92bf3ec2a30 (diff)
MessageQueue.isBlockedOnSyncBarrier() fixes
- add some missing checks for null references - we need to flush our trieber stack before checking for deliverable messages - mirror the changes into ConcurrentMessageQueue - also add some compile fixes to ConcurrentMessageQueue Test: atest TestLooperManagerTest Bug: 379472827 Flag: android.os.message_queue_testability Change-Id: I1072117781ffe7765fb9c8f51b39f09829b8435f
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java15
-rw-r--r--core/java/android/os/ConcurrentMessageQueue/MessageQueue.java24
-rw-r--r--core/java/android/os/LegacyMessageQueue/MessageQueue.java4
3 files changed, 28 insertions, 15 deletions
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index b509c7a441d3..230fa3fec930 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -1355,14 +1355,21 @@ public final class MessageQueue {
/**
* @return true if we are blocked on a sync barrier
+ *
+ * Calls to this method must not be allowed to race with `next`.
+ * Specifically, the Looper thread must be paused before calling this method,
+ * and may not be resumed until after returning from this method.
*/
boolean isBlockedOnSyncBarrier() {
throwIfNotTest();
if (mUseConcurrent) {
+ // Call nextMessage to get the stack drained into our priority queues
+ nextMessage(true);
+
Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
MessageNode queueNode = iterateNext(queueIter);
- if (queueNode.isBarrier()) {
+ if (queueNode != null && queueNode.isBarrier()) {
long now = SystemClock.uptimeMillis();
/* Look for a deliverable async node. If one exists we are not blocked. */
@@ -1375,14 +1382,12 @@ public final class MessageQueue {
* Look for a deliverable sync node. In this case, if one exists we are blocked
* since the barrier prevents delivery of the Message.
*/
- while (queueNode.isBarrier()) {
+ while (queueNode != null && queueNode.isBarrier()) {
queueNode = iterateNext(queueIter);
}
if (queueNode != null && now >= queueNode.getWhen()) {
return true;
}
-
- return false;
}
} else {
Message msg = mMessages;
@@ -1409,10 +1414,8 @@ public final class MessageQueue {
if (iter != null && now >= iter.when) {
return true;
}
- return false;
}
}
- /* No barrier was found. */
return false;
}
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index de0259eb1e36..d7d8e4199b33 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -19,6 +19,7 @@ package android.os;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.app.Instrumentation;
@@ -784,7 +785,7 @@ public final class MessageQueue {
mMessageDirectlyQueued = false;
nativePollOnce(ptr, mNextPollTimeoutMillis);
- Message msg = nextMessage();
+ Message msg = nextMessage(false);
if (msg != null) {
msg.markInUse();
return msg;
@@ -1087,7 +1088,6 @@ public final class MessageQueue {
*
* Caller must ensure that this doesn't race 'next' from the Looper thread.
*/
- @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
Long peekWhenForTest() {
throwIfNotTest();
Message ret = nextMessage(true);
@@ -1100,7 +1100,6 @@ public final class MessageQueue {
*
* Caller must ensure that this doesn't race 'next' from the Looper thread.
*/
- @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
@Nullable
Message pollForTest() {
throwIfNotTest();
@@ -1109,13 +1108,21 @@ public final class MessageQueue {
/**
* @return true if we are blocked on a sync barrier
+ *
+ * Calls to this method must not be allowed to race with `next`.
+ * Specifically, the Looper thread must be paused before calling this method,
+ * and may not be resumed until after returning from this method.
*/
boolean isBlockedOnSyncBarrier() {
throwIfNotTest();
+
+ // Call nextMessage to get the stack drained into our priority queues
+ nextMessage(true);
+
Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
MessageNode queueNode = iterateNext(queueIter);
- if (queueNode.isBarrier()) {
+ if (queueNode != null && queueNode.isBarrier()) {
long now = SystemClock.uptimeMillis();
/* Look for a deliverable async node. If one exists we are not blocked. */
@@ -1128,15 +1135,14 @@ public final class MessageQueue {
* Look for a deliverable sync node. In this case, if one exists we are blocked
* since the barrier prevents delivery of the Message.
*/
- while (queueNode.isBarrier()) {
+ while (queueNode != null && queueNode.isBarrier()) {
queueNode = iterateNext(queueIter);
}
if (queueNode != null && now >= queueNode.getWhen()) {
return true;
}
-
- return false;
}
+ return false;
}
private StateNode getStateNode(StackNode node) {
@@ -1193,7 +1199,7 @@ public final class MessageQueue {
MessageNode p = (MessageNode) top;
while (true) {
- if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+ if (compare.compareMessage(p, h, what, object, r, when)) {
found = true;
if (DEBUG) {
Log.w(TAG, "stackHasMessages node matches");
@@ -1238,7 +1244,7 @@ public final class MessageQueue {
while (iterator.hasNext()) {
MessageNode msg = iterator.next();
- if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+ if (compare.compareMessage(msg, h, what, object, r, when)) {
if (removeMatches) {
found = true;
if (queue.remove(msg)) {
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
index 5e1e1fdca5c8..c0333e914b4d 100644
--- a/core/java/android/os/LegacyMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -814,6 +814,10 @@ public final class MessageQueue {
/**
* @return true if we are blocked on a sync barrier
+ *
+ * Calls to this method must not be allowed to race with `next`.
+ * Specifically, the Looper thread must be paused before calling this method,
+ * and may not be resumed until after returning from this method.
*/
boolean isBlockedOnSyncBarrier() {
throwIfNotTest();