[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