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

Commit 803254d0 authored by Lee Shombert's avatar Lee Shombert
Browse files

Fix concurrency issue in PropertyInvalidatedCache

Bug: 253063488

Ensure the global lock is held while fetching the list of active
caches.  The global lock is necessary while the list is being fetched;
it is not necessary while each cache in the list is cleared.

Added a new test for PropertyInvalidatedCache.onTrimMemory().  This
test will not catch race conditions but does verify that
onTrimMemory() behaves as expected.

Test: atest
 * FrameworksCoreTests:PropertyInvalidatedCacheTests
Change-Id: I5022620cd4f2561179af709246a9bf149423143f
parent 03ffc41d
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -1405,6 +1405,17 @@ public class PropertyInvalidatedCache<Query, Result> {
        return isDisabled();
    }

    /**
     * Return the number of entries in the cache.  This is used for testing and has package-only
     * visibility.
     * @hide
     */
    public int size() {
        synchronized (mLock) {
            return mCache.size();
        }
    }

    /**
     * Returns a list of caches alive at the current time.
     */
@@ -1612,8 +1623,12 @@ public class PropertyInvalidatedCache<Query, Result> {
     * @hide
     */
    public static void onTrimMemory() {
        for (PropertyInvalidatedCache pic : getActiveCaches()) {
            pic.clear();
        ArrayList<PropertyInvalidatedCache> activeCaches;
        synchronized (sGlobalLock) {
            activeCaches = getActiveCaches();
        }
        for (int i = 0; i < activeCaches.size(); i++) {
            activeCaches.get(i).clear();
        }
    }
}
+16 −0
Original line number Diff line number Diff line
@@ -368,4 +368,20 @@ public class PropertyInvalidatedCacheTests {
            PropertyInvalidatedCache.MODULE_BLUETOOTH, "getState");
        assertEquals(n1, "cache_key.bluetooth.get_state");
    }

    @Test
    public void testOnTrimMemory() {
        TestCache cache = new TestCache(MODULE, "trimMemoryTest");
        // The cache is not active until it has been invalidated once.
        cache.invalidateCache();
        // Populate the cache with six entries.
        for (int i = 0; i < 6; i++) {
            cache.query(i);
        }
        // The maximum number of entries in TestCache is 4, so even though six entries were
        // created, only four are retained.
        assertEquals(4, cache.size());
        PropertyInvalidatedCache.onTrimMemory();
        assertEquals(0, cache.size());
    }
}