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

Commit 05d42ad0 authored by Garfield Tan's avatar Garfield Tan
Browse files

Ensure long wait time for the first item in PersisterQueue

Unit tests revealed a race condition where mNextWriteTime set in the
first PersisterQueue#addItem() can be overwritten by
PersisterQueue#processNextItem() if the item is added quickly after
starting the writer thread. This could defeat the overall purpose of
having a long wait to avoid competing with critical resources system
boots need.

Bug: 402243483
Test: atest --iterations 20 PersisterQueueTests
Flag: EXEMPT bug fix
Change-Id: I6ca44618999aca4674d6a8fbc5e02592dd25169a
parent 0fa17c84
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -232,8 +232,12 @@ class PersisterQueue {
        final WriteQueueItem item;
        synchronized (this) {
            if (mNextWriteTime != FLUSH_QUEUE) {
                // The next write we don't have to wait so long.
                mNextWriteTime = SystemClock.uptimeMillis() + mInterWriteDelayMs;
                // mNextWriteTime can be mPreTaskDelayMs from the time when the first item is added
                // before the writer thread enters this synchronized block for the first time. In
                // other cases, mNextWriteTime is the time when the last item was processed and we
                // don't need to wait so long to process the next task if the queue isn't empty.
                mNextWriteTime =
                    Math.max(mNextWriteTime, SystemClock.uptimeMillis() + mInterWriteDelayMs);
                if (DEBUG) {
                    Slog.d(TAG, "Next write time may be in " + mInterWriteDelayMs
                            + " msec. (" + mNextWriteTime + ")");
@@ -252,8 +256,7 @@ class PersisterQueue {
                }
                if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
                wait();
                // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
                // from now.
                // Invariant: mNextWriteTime is either FLUSH_QUEUE or mPreTaskDelayMs from now.
            }
            item = mWriteQueue.remove(0);