чт, 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

Reply via email to