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

Commit 6fb6f519 authored by Mark Fasheh's avatar Mark Fasheh
Browse files

MessageStack: add hasMessages()

We need this to implement the various hasMessages variants in DeliQueue.

Test: atest android.os.MessageStackTest
Bug: 421623328
Flag: EXEMPT new data structure isn't used yet; usages will be flagged.
Change-Id: I1fb3a8df100229e125b134ffb5d90ad804633d28
parent b95efc2c
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -117,6 +117,16 @@ public final class MessageStack {
        return m.when;
    }

    /**
     * Check that the message hasn't already been removed or processed elsewhere.
     */
    private boolean messageMatches(Message m, MessageQueue.MessageCompare compare, Handler h,
            int what, Object object, Runnable r, long when) {
        return !isQuittingMessage(m)
                && !m.isRemoved()
                && compare.compareMessage(m, h, what, object, r, when);
    }

    /**
     * Iterates through messages and creates a reverse-ordered chain of messages to remove.
     */
@@ -127,10 +137,7 @@ public final class MessageStack {
        Message firstRemoved = null;

        while (current != null) {
            // Check that the message hasn't already been removed or processed elsewhere.
            if (!isQuittingMessage(current)
                    && !current.isRemoved()
                    && compare.compareMessage(current, h, what, object, r, when)
            if (messageMatches(current, compare, h, what, object, r, when)
                    && current.markRemoved()) {
                if (firstRemoved == null) {
                    firstRemoved = current;
@@ -151,6 +158,24 @@ public final class MessageStack {
        } while (!sFreelistHead.compareAndSet(this, freelist, prev));
    }

    /**
     * Search our stack for a given set of messages.
     * @return true if matching messages are found, false otherwise.
     */
    public boolean hasMessages(MessageQueue.MessageCompare compare, Handler h, int what,
            Object object, Runnable r, long when) {
        Message current = (Message) sTop.getAcquire(this);

        while (current != null) {
            // Check that the message hasn't already been removed or processed elsewhere.
            if (messageMatches(current, compare, h, what, object, r, when)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    /**
     * Adds not-yet-processed messages into the MessageHeap and creates backlinks.
     */
+29 −0
Original line number Diff line number Diff line
@@ -132,6 +132,35 @@ public final class MessageStackTest {
        assertEquals(0, stack.combinedHeapSizesForTest());
    }

    /**
     * Test our basic message search.
     */
    @Test
    public void testHasMessages() {
        MessageStack stack = new MessageStack();
        Handler h = new Handler(Looper.getMainLooper());
        int skipWhat = 1;
        int findWhat = 2;

        // Interleave message types
        for (int i = 0; i < 5; i++) {
            stack.pushMessage(Message.obtain(h, skipWhat));
            stack.pushMessage(Message.obtain(h, findWhat));
        }

        assertTrue(stack.hasMessages(new MessageQueue.MatchHandlerWhatAndObject(),
                h, findWhat, null, null, 0));

        assertFalse(stack.hasMessages(new MessageQueue.MatchHandlerWhatAndObject(),
                h, 3, null, null, 0));

        stack.updateFreelist(new MessageQueue.MatchHandlerWhatAndObject(),
                h, findWhat, null, null, 0);

        assertFalse(stack.hasMessages(new MessageQueue.MatchHandlerWhatAndObject(),
                h, findWhat, null, null, 0));
    }

    /**
     * Push messages from multiple threads and verify stack and heap sizes.
     */