Fix concurrent modification during reads for SparseArray.
(Long)SparseArray is the only Android collection that may not be safe
for concurrent reads, due to its gc() mechanism.
Specifically, during any removal (excluding clear()) (Long)SparseArray
would only set the value to DELETED and mark itself as mGarbage, but
won't actually remove the mapping - the mapping removal will only
happen in the gc() method called during the next read operation. This
helps minimizing the cost of consecutive removals, but also makes read
operations actually mutating its internal state and thus reads are no
longer thread safe when mGarbage is set.
No other Android collections are doing this (not even
SparseBooleanArray), and our mutations aren't super frequent, so we
should just force a gc() after removals, which is trivially doable by
invoking the size() method.
Bug: 263504888
Test: presubmit
Change-Id: Idf0ff5f8cda396162e0d52e1d2f56d8079b2d91b
2 files changed