I discovered a deadlock in the current version of the generator (fe5b7f84a10d062e1d79e17a8d21f860ab8b2aa0).
The method call in the class QueryCallable needs to acquire a permit from the semaphore limiter to be executed. However, this code can recursively call the call method again, which again needs to acquire a permit. If the semaphore limit is exhausted and all running call methods try to acquire permits for their recursive calls, then the deadlock occurs.
This is exactly what happened in my case, all the pool threads got deadlocked in this state:
"pool-115-thread-1" #224 [53758] prio=5 os_prio=0 cpu=1.14ms elapsed=8034.60s tid=0x00007f8d345c49e0 nid=53758 waiting on condition [0x00007f8a2c4fe000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x000000011a00ae38> (a java.util.concurrent.Semaphore$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:221)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21/AbstractQueuedSynchronizer.java:754)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(java.base@21/AbstractQueuedSynchronizer.java:1079)
at java.util.concurrent.Semaphore.acquireUninterruptibly(java.base@21/Semaphore.java:341)
at swiss.sib.swissprot.voidcounter.QueryCallable.call(QueryCallable.java:27)
at swiss.sib.swissprot.servicedescription.FindPredicatesAndClasses.run(FindPredicatesAndClasses.java:64)
at swiss.sib.swissprot.servicedescription.FindPredicatesAndClasses.run(FindPredicatesAndClasses.java:23)
at swiss.sib.swissprot.voidcounter.QueryCallable.call(QueryCallable.java:31)
at swiss.sib.swissprot.voidcounter.QueryCallable.call(QueryCallable.java:11)
at java.util.concurrent.FutureTask.run(java.base@21/FutureTask.java:317)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21/ThreadPoolExecutor.java:1144)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21/ThreadPoolExecutor.java:642)
at java.lang.Thread.runWith(java.base@21/Thread.java:1596)
at java.lang.Thread.run(java.base@21/Thread.java:1583)
Fixed this by no longer recursively calling call. Instead passing in a Supplier for the relevant QueryCallable to schedule more work upon completion. 393bdb490a605239856135fb0dd52f18329229b7 should fix this
I discovered a deadlock in the current version of the generator (fe5b7f84a10d062e1d79e17a8d21f860ab8b2aa0).
The method
call
in the classQueryCallable
needs to acquire a permit from the semaphorelimiter
to be executed. However, this code can recursively call thecall
method again, which again needs to acquire a permit. If the semaphore limit is exhausted and all runningcall
methods try to acquire permits for their recursive calls, then the deadlock occurs.This is exactly what happened in my case, all the pool threads got deadlocked in this state: