gnodet commented on issue #12472:
URL: https://github.com/apache/maven/issues/12472#issuecomment-4955394126

   ## Root Cause Analysis
   
   I investigated this hang and traced it to a **cross-thread deadlock** in 
`AbstractRequestCache.requests()` — the batch request caching mechanism used 
during dependency resolution.
   
   ### The deadlock mechanism (in rc-5)
   
   1. **Thread A** calls `requests([artifactA, sharedDep])` — creates 
`CachingSupplier` instances and stores them in the cache (`SoftIdentityMap`)
   2. **Thread B** calls `requests([artifactB, sharedDep])` — gets back the 
**same** `CachingSupplier` for `sharedDep` because `SoftIdentityMap` used 
`equals()` (despite "Identity" in the name)
   3. Thread B enters `CachingSupplier.apply()` for `sharedDep`, hits the 
`individualSupplier` lambda which does `synchronized(nonCachedResults) { wait() 
}` — waiting for Thread A's `IdentityHashMap`
   4. Thread A's batch supplier completes and tries to populate results, but 
Thread B holds the `CachingSupplier`'s monitor (via `synchronized(this)` in 
`apply()`)
   5. **Permanent deadlock**: Thread A can't deliver the result, Thread B can't 
receive it
   
   ### Fix already on master
   
   This was already fixed in commit c6de104bff 
([#12446](https://github.com/apache/maven/pull/12446)) which replaced the 
`individualSupplier` + `IdentityHashMap` wait pattern with:
   - `CachingSupplier.complete()` — directly sets the value and calls 
`notifyAll()`, no external map needed
   - `ThreadLocal` re-entrancy guard — prevents same-thread deadlocks when 
batch resolution triggers nested calls (e.g., parent POM resolution)
   - `singleSupplier` fallback — re-entrant calls resolve individually instead 
of waiting
   
   ### Regression test
   
   I've added a specific cross-thread deadlock regression test in 
[#12478](https://github.com/apache/maven/pull/12478) that reproduces the exact 
scenario: two threads calling `requests()` with overlapping keys through a 
shared equals-based cache, using a `CyclicBarrier` to force concurrent 
execution. This test would deadlock on rc-5 code but passes on master.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to