docs: Add a concurrency section to AGENTS.md - #6009
Draft
runningcode wants to merge 1 commit into
Draft
Conversation
Two production ANRs in the Android SDK came from holding a lock across a call that re-enters the SDK: finishing a span or transaction captures synchronously on the calling thread and runs every event processor, and those processors lock and call back into the component that is still holding its own lock. Write the rule down next to the exception-handling guidance, with the snapshot-then-call pattern, the second-lock escape hatch for compound operations that were only atomic because the lock spanned them, and the volatile and single-read rules. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 Description
Adds a Concurrency section to
AGENTS.md, next to the existing exception-handling guidance. The core rule: never hold a lock across a call that can re-enter the SDK — read what you need under the lock, release it, then make the call.Also covers the second-lock escape hatch for compound operations that were only atomic because the lock spanned them, plus two supporting rules (
volatilefor cross-thread fields, and reading mutable shared state once per operation).💡 Motivation and Context
Requested by @buenaflor while reviewing #6007.
Two production ANRs came from the same mistake. In #6007,
AppStartExtensionheld its lock while callingfinish()on the app start transaction; finishing captures synchronously and runsPerformanceAndroidEventProcessor, which takes its own lock and then calls back intoAppStartExtension— opposite lock order, main thread blocked, ANR. JAVA-553 was the same shape inReplayIntegration. Thevolatileand single-read rules come from #6006, whereAppStartMetrics.appStartTypewas read three times in one pass and could disagree with itself.The exception-handling section already establishes the format for this kind of repository-wide rule, so this follows it: the rule, why it fails, a wrong/right code pair, and the scope.
💚 How did you test it?
Documentation only.
./gradlew spotlessApplyis clean.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
Independent of #6007 — this documents the rule, that PR fixes the instance.
#skip-changelog