Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19f88e9f authored by Mark Fasheh's avatar Mark Fasheh
Browse files

Avoid races between nextMessage() and stackHasMessages()

Always check if the stack is draining before we exit stackHasMessages().
 - This will ensure that next has put any pending messages into the
   priority queues before we search them.

Bug: 396569494
Flag: EXEMPT - bugfix
Test: atest MessageQueueTest
Change-Id: If3259e13060baae4125a4977519a7f08390f79cb
parent 318fcc18
Loading
Loading
Loading
Loading
+6 −15
Original line number Diff line number Diff line
@@ -2563,10 +2563,6 @@ public final class MessageQueue {
            return mMessage.when;
        }

        boolean isRemovedFromStack() {
            return mRemovedFromStackValue;
        }

        boolean removeFromStack() {
            return sRemovedFromStack.compareAndSet(this, false, true);
        }
@@ -2919,16 +2915,10 @@ public final class MessageQueue {
        StateNode bottom = getStateNode(top);

        /*
         * If the top node is a state node, there are no reachable messages.
         * If it's anything other than Active, we can quit as we know that next() is not
         * consuming items.
         * If the top node is Active then we know that next() is currently consuming items.
         * In that case we should wait next() has drained the stack.
         * If the top node is a state node, there are no reachable messages. We should still
         * wait for next to complete draining the stack.
         */
        if (top == bottom) {
            if (bottom != sStackStateActive) {
                return false;
            }
            waitForDrainCompleted();
            return false;
        }
@@ -2957,7 +2947,7 @@ public final class MessageQueue {
                        }
                    }
                } else {
                    return true;
                    break;
                }
            }

@@ -2967,16 +2957,17 @@ public final class MessageQueue {
                if (DEBUG) {
                    Log.d(TAG_C, "stackHasMessages next() is walking the stack, we must re-sample");
                }
                waitForDrainCompleted();
                break;
            }
            if (!n.isMessageNode()) {
                /* We reached the end of the stack */
                return found;
                break;
            }
            p = (MessageNode) n;
        }

        waitForDrainCompleted();

        return found;
    }