чт, 18 июл. 2024 г. в 11:42, <ma...@apache.org>: > > This is an automated email from the ASF dual-hosted git repository. > > markt pushed a commit to branch 1.3.x > in repository https://gitbox.apache.org/repos/asf/tomcat-native.git > > > The following commit(s) were added to refs/heads/1.3.x by this push: > new e7a329999 Align with 9.0.x > e7a329999 is described below > > commit e7a329999c66948689f450a320d92a06c6ad14e9 > Author: Mark Thomas <ma...@apache.org> > AuthorDate: Thu Jul 18 09:38:15 2024 +0100 > > Align with 9.0.x > --- > java/org/apache/tomcat/jni/Library.java | 55 > ++++++++++++++++++++++++++++++--- > 1 file changed, 51 insertions(+), 4 deletions(-) > > diff --git a/java/org/apache/tomcat/jni/Library.java > b/java/org/apache/tomcat/jni/Library.java > index 218a101b5..c8e62f4a2 100644 > --- a/java/org/apache/tomcat/jni/Library.java > +++ b/java/org/apache/tomcat/jni/Library.java > @@ -17,6 +17,10 @@ > package org.apache.tomcat.jni; > > import java.io.File; > +import java.util.concurrent.TimeUnit; > +import java.util.concurrent.atomic.AtomicLong; > +import java.util.concurrent.locks.ReadWriteLock; > +import java.util.concurrent.locks.ReentrantReadWriteLock; > > public final class Library { > > @@ -32,6 +36,9 @@ public final class Library { > */ > private static Library _instance = null; > > + private static final AtomicLong generation = new AtomicLong(0); > + private static final ReadWriteLock cleanUpLock = new > ReentrantReadWriteLock(); > + > private Library() throws Exception { > boolean loaded = false; > StringBuilder err = new StringBuilder(); > @@ -100,12 +107,30 @@ public final class Library { > System.loadLibrary(libraryName); > } > > - /* create global TCN's APR pool > - * This has to be the first call to TCN library. > + /** > + * Create Tomcat Native's global APR pool. This has to be the first call > to TCN library. > */ > private static native boolean initialize(); > - /* destroy global TCN's APR pool > - * This has to be the last call to TCN library. > + /** > + * Allows for thread safe termination when other threads may be > attempting clean-up concurrently with the current > + * thread. Waits for any threads currently holding the clean-up lock to > release the lock and then calls > + * {@link #terminate()}. > + */ > + public static void threadSafeTerminate() { > + cleanUpLock.writeLock().lock(); > + try { > + terminate(); > + } finally { > + generation.incrementAndGet(); > + cleanUpLock.writeLock().unlock(); > + } > + } > + /** > + * Destroys Tomcat Native's global APR pool. This has to be the last > call to TCN library. This will destroy any APR > + * root pools that have not been explicitly destroyed. > + * <p> > + * This method should only be used if the caller is certain that all > other threads have finished using the native > + * library. > */ > public static native void terminate(); > /* Internal function for loading APR Features */ > @@ -287,6 +312,28 @@ public final class Library { > return initialize(); > } > > + > + public static boolean tryCleanUpLock(long cleanupGeneration) { > + try { > + boolean result = cleanUpLock.readLock().tryLock(0, > TimeUnit.SECONDS); > + if (result && generation.get() == cleanupGeneration) { > + return true; > + } > + cleanUpLock.readLock().unlock(); > + } catch (InterruptedException e) { > + // Treated the same way as not getting the lock > + } > + return false; > + }
Mark, I think there is a bug with the "readLock().unlock()" call above. It should be called only when the "result" of preceding tryLock() is true. Calling unlock() when no lock is held results in an IllegalMonitorStateException. [1] I see that this code is present on the 9.0.x branch only (and not on the 10.1.x and main branches). [1] https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.ReadLock.html > + public static long getGeneration() { > + return generation.get(); > + } > + > + public static void returnCleanUpLock() { > + cleanUpLock.readLock().unlock(); > + } > + > /** > * Calls System.load(filename). System.load() associates the > * loaded library with the class loader of the class that called Best regards, Konstantin Kolinko --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org