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

Commit 7aa6729b authored by Charles Munger's avatar Charles Munger
Browse files

Always clear heap index when removing items

Flag: build.RELEASE_PACKAGE_MESSAGEQUEUE_IMPLEMENTATION
BUG=444085764
Change-Id: I5256baa1d00793c2e1f4bd538a45599093e79f35
parent c0bbfb05
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -91,11 +91,12 @@ public final class MessageHeap {
    }

    private void swap(int x, int y) {
        Message tmp = mHeap[x];
        mHeap[x] = mHeap[y];
        mHeap[y] = tmp;
        mHeap[x].heapIndex = x;
        mHeap[y].heapIndex = y;
        Message newX = mHeap[y];
        Message newY = mHeap[x];
        mHeap[x] = newX;
        mHeap[y] = newY;
        newX.heapIndex = x;
        newY.heapIndex = y;
    }

    private void siftDown(int i) {
@@ -205,6 +206,7 @@ public final class MessageHeap {
            mHeap[0] = mHeap[mNumElements];
            mHeap[0].heapIndex = 0;
            mHeap[mNumElements] = null;
            ret.heapIndex = -1;

            siftDown(0);

@@ -222,11 +224,12 @@ public final class MessageHeap {
        if (i >= mNumElements || mNumElements == 0 || i < 0) {
            throw new IllegalArgumentException("Index " + i + " out of bounds: "
                    + mNumElements);
        } else if (i == (mNumElements - 1)) {
            mHeap[i] = null;
        }
        mNumElements--;
        mHeap[i].heapIndex = -1;
        if (i == mNumElements) {
            mHeap[i] = null;
        } else {
            mNumElements--;
            mHeap[i] = mHeap[mNumElements];
            mHeap[i].heapIndex = i;
            mHeap[mNumElements] = null;
@@ -234,17 +237,17 @@ public final class MessageHeap {
                siftDown(i);
            }
        }
        /* Don't shink here, let the caller do this once it has removed all matching items. */
        /* Don't shrink here, let the caller do this once it has removed all matching items. */
    }

    public void removeMessage(@NonNull Message m) throws IllegalArgumentException {
        // We set this index to be out of range so that we don't attempt to remove this message from
        // the heap a second time (e.g. when it's processed on the MessageStack freelist).
        remove(m.heapIndex);
        m.heapIndex = -1;
    }

    public void removeAll() {
        for (int i = 0; i < mNumElements; i++) {
            mHeap[i].heapIndex = -1;
        }
        mHeap = new Message[INITIAL_SIZE];
        mNumElements = 0;
    }
+17 −22
Original line number Diff line number Diff line
@@ -228,7 +228,8 @@ public final class MessageStack {
        while (current != null) {
            Message nextFree = current.nextFree;
            current.nextFree = null;
            removeMessage(current, /* removeFromHeap= */ true);
            maybeRemoveFromHeap(current);
            removeFromStack(current);
            current = nextFree;
        }
    }
@@ -248,7 +249,7 @@ public final class MessageStack {
            if (!m.markRemoved()) {
                return null;
            }
            removeMessage(m, /* removeFromHeap= */ false);
            removeFromStack(m);
        }
        return m;
    }
@@ -264,24 +265,22 @@ public final class MessageStack {
        }
    }

    /**
     * Remove a message from the stack.
     *
     * removeFromHeap indicates if the message should be removed from the heap (if this message is
     * being drained from the freelist) or not (if this message was retrieved using
     * MessageHeap.pop()).
     */
    private void removeMessage(Message m, boolean removeFromHeap) {
        // An out of range heapIndex means that we've already removed this message from the heap
        // during the MessageHeap.peek() loop in peek().
        if (removeFromHeap && m.heapIndex >= 0) {
    private void maybeRemoveFromHeap(Message m) {
        // An out of range heapIndex means that we've already removed this message from the heap, or
        // it was never added to the heap in the first place.
        if (m.heapIndex >= 0) {
            if (m.isAsynchronous()) {
                mAsyncHeap.removeMessage(m);
            } else {
                mSyncHeap.removeMessage(m);
            }
        }
    }

    /**
     * Remove a message from the stack.
     */
    private void removeFromStack(Message m) {
        // mLooperProcessed must be updated to the next message that hasn't been removed.
        if (m == mLooperProcessed) {
            do {
@@ -328,21 +327,16 @@ public final class MessageStack {
     * removed messages.
     */
    public @Nullable Message peek(boolean async) {
        MessageHeap heap = async ? mAsyncHeap : mSyncHeap;
        while (true) {
            final Message m = async ? mAsyncHeap.peek() : mSyncHeap.peek();
            final Message m = heap.peek();
            if (m == null) {
                return null;
            }
            if (!m.isRemoved()) {
                return m;
            }
            if (m.heapIndex >= 0) {
                if (async) {
                    mAsyncHeap.removeMessage(m);
                } else {
                    mSyncHeap.removeMessage(m);
                }
            }
            heap.removeMessage(m);
        }
    }

@@ -352,7 +346,8 @@ public final class MessageStack {
     * This is suitable to use with the output of peek().
     */
    public void remove(Message m) {
        removeMessage(m, /* removeFromHeap= */ true);
        maybeRemoveFromHeap(m);
        removeFromStack(m);
    }

    Message peekLastMessageForTest() {