Replace Mutex with CountDownLatch to fix ANR on cold start#7996
Replace Mutex with CountDownLatch to fix ANR on cold start#7996mrober merged 3 commits intofirebase:mainfrom
Conversation
CrashlyticsRegistrar.<clinit> calls FirebaseSessionsDependencies.addDependency() which creates a kotlinx.coroutines.sync.Mutex. This triggers loading the entire coroutines synchronization class chain on the main thread during Class.forName(), causing ANRs on budget devices before Application.onCreate(). Replace Mutex with java.util.concurrent.CountDownLatch — a JVM primitive with zero class-loading overhead that provides identical one-shot gate semantics. Fixes firebase#7882 I have also added a test cases representing the times to load both approaches
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
ebad1de to
7facb69
Compare
Summary
loading the entire kotlinx.coroutines synchronization infrastructure on the main thread
FirebaseSessionsDependencies — a JVM primitive with zero class-loading overhead and identical one-shot gate
semantics
Problem #7882(#7882)
When ComponentDiscovery loads CrashlyticsRegistrar via Class.forName() on the main thread, the static block
calls FirebaseSessionsDependencies.addDependency(), which creates a Mutex(locked = true). This cascades into
loading ~10 coroutines classes (SemaphoreAndMutexImpl, SemaphoreSegment, ConcurrentLinkedListNode,
SystemPropsKt, etc.) via chains — all before Application.onCreate(). On budget devices where APK
class loading is slow, this may exceed the ANR timeout.
Fix
The Mutex was only used as a one-shot gate (create locked, unlock once when registered, waiters proceed).
CountDownLatch(1) provides the exact same semantics as a JVM bootstrap class with no additional class loading.
runInterruptible { latch.await() } preserves suspend/cancellation support in getRegisteredSubscribers().
I have also added a test cases representing the times to load both approaches, here's the result