[jffi-next] 16/22: Start merging back ClosurePool from default branch

Tim Potter tpot-guest at moszumanska.debian.org
Wed Mar 4 04:51:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

tpot-guest pushed a commit to tag 0.6.0.1
in repository jffi-next.

commit ac85b232610b9682ae0fa634cba51d0801fb75e7
Author: Wayne Meissner <wmeissner at gmail.com>
Date:   Tue Oct 13 19:03:14 2009 +1000

    Start merging back ClosurePool from default branch
---
 src/com/kenai/jffi/ClosureManager.java             | 164 ++++-----------------
 .../jffi/{ClosureManager.java => ClosurePool.java} |  46 ++----
 2 files changed, 40 insertions(+), 170 deletions(-)

diff --git a/src/com/kenai/jffi/ClosureManager.java b/src/com/kenai/jffi/ClosureManager.java
index 94fde50..2cb1084 100644
--- a/src/com/kenai/jffi/ClosureManager.java
+++ b/src/com/kenai/jffi/ClosureManager.java
@@ -1,14 +1,24 @@
 
 package com.kenai.jffi;
 
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.Map;
+import java.util.WeakHashMap;
 
 /**
- * Allocates and manages the lifecycle of native closures (aka callbacks).rm hs
+ * Allocates and manages the lifecycle of native closures (aka callbacks)
  */
 public class ClosureManager {
-    private static final Object lock = new Object();
+
+    /**
+     * ClosurePool instances are linked via a SoftReference in the lookup map, so
+     * when all closure instances that that were allocated from the ClosurePool have been
+     * reclaimed, and there is memory pressure, the native closure pool can be freed.
+     * This will allow the CallContext instance to also be collected if it is not
+     * strongly referenced elsewhere, and ejected from the {@link CallContextCache}
+     */
+    private final Map<CallContext, Reference<ClosurePool>> poolMap = new WeakHashMap<CallContext, Reference<ClosurePool>>();
 
     /** Holder class to do lazy allocation of the ClosureManager instance */
     private static final class SingletonHolder {
@@ -41,143 +51,31 @@ public class ClosureManager {
         return newClosure(closure, CallContextCache.getInstance().getCallContext(returnType, parameterTypes, convention));
     }
 
-    public final Closure.Handle newClosure(Closure closure, CallContext ctx) {
-        Proxy proxy = new Proxy(closure, ctx);
-
-        long handle = 0;
-        synchronized (lock) {
-            handle = Foreign.getInstance().newClosure(proxy, Proxy.METHOD,
-                ctx.nativeReturnType, ctx.nativeParameterTypes, ctx.flags);
-        }
-        if (handle == 0) {
-            throw new RuntimeException("Failed to create native closure");
-        }
-
-        return new Handle(handle, ctx);
-    }
-
     /**
-     * Manages the lifecycle of a native closure.
+     * Wraps a java object that implements the {@link Closure} interface in a
+     * native closure.
      *
-     * Implements {@link Closure.Handle} interface.
+     * @param closure The java object to be called when the native closure is invoked.
+     * @param returnType The return type of the closure.
+     * @param parameterTypes The parameter types of the closure.
+     * @param convention The calling convention of the closure.
+     * @return A new {@link Closure.Handle} instance.
      */
-    private static final class Handle implements Closure.Handle {
-        /** Store a reference to the MemoryIO accessor here for easy access */
-        private static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
-
-        private final AtomicBoolean released = new AtomicBoolean(false);
-        private volatile boolean autorelease = true;
-
-        /**
-         * The address of the native closure structure.
-         *
-         * <b>Note:</b> This is <b>NOT</b> the code address, but a pointer to the structure
-         * which contains the code address.
-         */
-        final long handle;
+    public final Closure.Handle newClosure(Closure closure, CallContext callContext) {
+        ClosurePool pool = getClosurePool(callContext);
 
-        /** The code trampoline address */
-        final long cbAddress;
-
-        /** 
-         * Keep references to the return and parameter types so they do not get
-         * garbage collected until the closure does.
-         */
-        private final CallContext ctx;
-
-        /**
-         * Creates a new Handle to lifecycle manager the native closure.
-         *
-         * @param handle The address of the native closure structure.
-         */
-        Handle(long handle, CallContext ctx) {
-            this.handle = handle;
-            cbAddress = IO.getAddress(handle);
-            this.ctx = ctx;
-        }
-
-        public long getAddress() {
-            return cbAddress;
-        }
-
-        public void setAutoRelease(boolean autorelease) {
-            this.autorelease = autorelease;
-        }
-
-        public void free() { dispose(); }
-
-        public void dispose() {
-            if (released.getAndSet(true)) {
-                throw new IllegalStateException("Closure already released");
-            }
-            synchronized (lock) {
-                Foreign.getInstance().freeClosure(handle);
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (autorelease && !released.getAndSet(true)) {
-                    synchronized (lock) {
-                        Foreign.getInstance().freeClosure(handle);
-                    }
-                }
-            } catch (Throwable t) {
-                t.printStackTrace(System.err);
-            } finally {
-                super.finalize();
-            }
-        }
+        return pool.newClosureHandle(closure);
     }
 
-    /**
-     * This is a proxy passed to the native code, to be called by the
-     * native trampoline code.
-     */
-    private static final class Proxy {
-        static final Method METHOD = getMethod();
-        final Closure closure;
-        
-        /** 
-         * Keep references to the return and parameter types so they do not get
-         * garbage collected until the closure does.
-         */
-        final CallContext ctx;
-
-        /**
-         * Gets the
-         * @return
-         */
-        private static  final Method getMethod() {
-            try {
-                return Proxy.class.getDeclaredMethod("invoke", new Class[] { long.class, long.class });
-            } catch (Throwable ex) {
-                throw new RuntimeException(ex);
-            }
+    private final synchronized ClosurePool getClosurePool(CallContext callContext) {
+        Reference<ClosurePool> ref = poolMap.get(callContext);
+        ClosurePool pool;
+        if (ref != null && (pool = ref.get()) != null) {
+            return pool;
         }
 
-        /**
-         * Creates a new <tt>Proxy</tt> instance.
-         *
-         * @param closure The closure to call when this proxy is invoked
-         * @param returnType The native return type of the closure
-         * @param parameterTypes The parameterTypes of the closure
-         */
-        Proxy(Closure closure, CallContext ctx) {
-            this.closure = closure;
-            this.ctx = ctx;
-        }
+        poolMap.put(callContext, new SoftReference<ClosurePool>(pool = new ClosurePool(callContext)));
 
-        /**
-         * Invoked by the native closure trampoline to execute the java side of
-         * the closure.
-         *
-         * @param retvalAddress The address of the native return value buffer
-         * @param paramAddress The address of the native parameter buffer.
-         */
-        void invoke(long retvalAddress, long paramAddress) {
-            closure.invoke(new DirectClosureBuffer(ctx, retvalAddress, paramAddress));
-        }
+        return pool;
     }
 }
diff --git a/src/com/kenai/jffi/ClosureManager.java b/src/com/kenai/jffi/ClosurePool.java
similarity index 75%
copy from src/com/kenai/jffi/ClosureManager.java
copy to src/com/kenai/jffi/ClosurePool.java
index 94fde50..7fd2694 100644
--- a/src/com/kenai/jffi/ClosureManager.java
+++ b/src/com/kenai/jffi/ClosurePool.java
@@ -4,44 +4,16 @@ package com.kenai.jffi;
 import java.lang.reflect.Method;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-/**
- * Allocates and manages the lifecycle of native closures (aka callbacks).rm hs
- */
-public class ClosureManager {
+public class ClosurePool {
     private static final Object lock = new Object();
 
-    /** Holder class to do lazy allocation of the ClosureManager instance */
-    private static final class SingletonHolder {
-        static final ClosureManager INSTANCE = new ClosureManager();
-    }
-
-    /**
-     * Gets the global instance of the <tt>ClosureManager</tt>
-     *
-     * @return An instance of a <tt>ClosureManager</tt>
-     */
-    public static final ClosureManager getInstance() {
-        return SingletonHolder.INSTANCE;
-    }
-
-    /** Constructs a ClosureManager */
-    private ClosureManager() { }
+    private final CallContext ctx;
 
-    /**
-     * Wraps a java object that implements the {@link Closure} interface in a
-     * native closure.
-     *
-     * @param closure The java object to be called when the native closure is invoked.
-     * @param returnType The return type of the closure.
-     * @param parameterTypes The parameter types of the closure.
-     * @param convention The calling convention of the closure.
-     * @return A new {@link Closure.Handle} instance.
-     */
-    public final Closure.Handle newClosure(Closure closure, Type returnType, Type[] parameterTypes, CallingConvention convention) {
-        return newClosure(closure, CallContextCache.getInstance().getCallContext(returnType, parameterTypes, convention));
+    public ClosurePool(CallContext ctx) {
+        this.ctx = ctx;
     }
-
-    public final Closure.Handle newClosure(Closure closure, CallContext ctx) {
+    
+    Closure.Handle newClosureHandle(Closure closure) {
         Proxy proxy = new Proxy(closure, ctx);
 
         long handle = 0;
@@ -79,7 +51,7 @@ public class ClosureManager {
         /** The code trampoline address */
         final long cbAddress;
 
-        /** 
+        /**
          * Keep references to the return and parameter types so they do not get
          * garbage collected until the closure does.
          */
@@ -138,8 +110,8 @@ public class ClosureManager {
     private static final class Proxy {
         static final Method METHOD = getMethod();
         final Closure closure;
-        
-        /** 
+
+        /**
          * Keep references to the return and parameter types so they do not get
          * garbage collected until the closure does.
          */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jffi-next.git



More information about the pkg-java-commits mailing list