Retry and ignore ConcurrentModificationException
The flaky callstack shows that it hits the exception in the
initialization of HashSet. The mNetworkRequests is accessed in
the ConnectivityService handler thread except dump(). The
ConcurrentModificationException should not happen in the other
flow. Thus, retry to get the current requests when the dump()
hits the ConcurrentModificationException to prevent flaky test.
Bug: 188373832
Test: atest ConnectivityServiceTest#testDumpDoesNotCrash\
--iteration 100
Change-Id: I9625919faf947c9488764b92093ed8105271c927
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index f8f280a..482bb73 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3162,7 +3162,18 @@
}
private void dumpNetworkRequests(IndentingPrintWriter pw) {
- for (NetworkRequestInfo nri : requestsSortedById()) {
+ NetworkRequestInfo[] infos = null;
+ while (infos == null) {
+ try {
+ infos = requestsSortedById();
+ } catch (ConcurrentModificationException e) {
+ // mNetworkRequests should only be accessed from handler thread, except dump().
+ // As dump() is never called in normal usage, it would be needlessly expensive
+ // to lock the collection only for its benefit. Instead, retry getting the
+ // requests if ConcurrentModificationException is thrown during dump().
+ }
+ }
+ for (NetworkRequestInfo nri : infos) {
pw.println(nri.toString());
}
}