On Tue, 11 May 2021 13:10:30 GMT, Aleksei Voitylov <avoity...@openjdk.org> 
wrote:

> Please review this PR which fixes the deadlock in ClassLoader between the two 
> lock objects - a lock object associated with the class being loaded, and the 
> ClassLoader.loadedLibraryNames hash map, locked during the native library 
> load operation.
> 
> Problem being fixed:
> 
> The initial reproducer demonstrated a deadlock between the JarFile/ZipFile 
> and the hash map. That deadlock exists even when the ZipFile/JarFile lock is 
> removed because there's another lock object in the class loader, associated 
> with the name of the class being loaded. Such objects are stored in 
> ClassLoader.parallelLockMap. The deadlock occurs when JNI_OnLoad() loads 
> exactly the same class, whose signature is being verified in another thread.
> 
> Proposed fix:
> 
> The proposed patch suggests to get rid of locking loadedLibraryNames hash map 
> and synchronize on each entry name, as it's done with class names in see 
> ClassLoader.getClassLoadingLock(name) method.
> 
> The patch introduces nativeLibraryLockMap which holds the lock objects for 
> each library name, and the getNativeLibraryLock() private method is used to 
> lazily initialize the corresponding lock object. nativeLibraryContext was 
> changed to ThreadLocal, so that in any concurrent thread it would have a 
> NativeLibrary object on top of the stack, that's being currently 
> loaded/unloaded in that thread. nativeLibraryLockMap accumulates the names of 
> all native libraries loaded - in line with class loading code, it is not 
> explicitly cleared.
> 
> Testing:  jtreg and jck testing with no regressions. A new regression test 
> was developed.

Hi Aleksei,
If I understand David Holmes correctly (on the mailing list), there is a 
concern that using a per-library-name exclusive lock might not be enough to 
prevent deadlock with class loading lock. You say: "The deadlock occurs when 
JNI_OnLoad() loads exactly the same class, whose signature is being verified in 
another thread." ... Could you explain a little bit more about this scenario? 
As I understand the JNI_OnLoad() is called as part of native library loading 
and at that time the thread that is loading native library holds a 
nativeLibraryLock(libraryName). Now if JNI_OnLoad() triggers loading of a 
class, whose signature is being verified in another thread (do you mean: which 
is already being loaded in another thread?) then JNI_OnLoad() thread will block 
on classLoadingLock(className). But that is not a dead-lock yet. The loading of 
a class in another thread now has to attempt to load the same native library 
that is being loaded in the JNI_OnLoad() thread.
So before the proposed patch it was enough for the other thread which was 
loading the class to trigger loading of any native library, while after the 
proposed patch, the deadlock would occur only if it triggered loading of the 
same native library. Am I correctly assessing the problem?

-------------

PR: https://git.openjdk.java.net/jdk/pull/3976

Reply via email to