[jffi-next] 09/49: Keep a reference to the Foreign instance in objects that need to release resources in a finalizer. Stops the Foreign class being GC'd before any class that needs to use it gets GC'd.
Tim Potter
tpot-guest at moszumanska.debian.org
Wed Mar 4 04:51:09 UTC 2015
This is an automated email from the git hooks/post-receive script.
tpot-guest pushed a commit to annotated tag upstream/1.0.10
in repository jffi-next.
commit cd8c2af1c2f9c3e2ee8e5cfb70b8ee4c7f5b649e
Author: Wayne Meissner <wmeissner at gmail.com>
Date: Sat Jan 1 22:26:27 2011 +1000
Keep a reference to the Foreign instance in objects that need to release resources in a finalizer. Stops the Foreign class being GC'd before any class that needs to use it gets GC'd.
---
src/com/kenai/jffi/Aggregate.java | 22 +++++++++++++++++-----
src/com/kenai/jffi/Array.java | 2 +-
src/com/kenai/jffi/CallContext.java | 17 ++++++++++++-----
src/com/kenai/jffi/ClosurePool.java | 9 ++++++---
src/com/kenai/jffi/Function.java | 17 ++++++++++++-----
src/com/kenai/jffi/LastError.java | 7 ++++---
src/com/kenai/jffi/Library.java | 21 ++++++++++++---------
src/com/kenai/jffi/MemoryIO.java | 4 ++--
src/com/kenai/jffi/PageManager.java | 14 ++++++++++----
src/com/kenai/jffi/Struct.java | 2 +-
src/com/kenai/jffi/Union.java | 2 +-
11 files changed, 78 insertions(+), 39 deletions(-)
diff --git a/src/com/kenai/jffi/Aggregate.java b/src/com/kenai/jffi/Aggregate.java
index 4be8246..e8f0107 100644
--- a/src/com/kenai/jffi/Aggregate.java
+++ b/src/com/kenai/jffi/Aggregate.java
@@ -18,6 +18,9 @@
package com.kenai.jffi;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
public abstract class Aggregate extends Type {
/** The FFI type of this type */
private final int type;
@@ -32,14 +35,22 @@ public abstract class Aggregate extends Type {
private volatile boolean disposed = false;
+ /** A handle to the foreign interface to keep it alive as long as this object is alive */
+ private final Foreign foreign;
+
public Aggregate(long handle) {
+ this(Foreign.getInstance(), handle);
+ }
+
+ Aggregate(Foreign foreign, long handle) {
if (handle == 0L) {
throw new NullPointerException("Invalid ffi_type handle");
}
+ this.foreign = foreign;
this.handle = handle;
- this.type = Foreign.getInstance().getTypeType(handle);
- this.size = Foreign.getInstance().getTypeSize(handle);
- this.align = Foreign.getInstance().getTypeAlign(handle);
+ this.type = foreign.getTypeType(handle);
+ this.size = foreign.getTypeSize(handle);
+ this.align = foreign.getTypeAlign(handle);
}
final long handle() {
@@ -64,7 +75,7 @@ public abstract class Aggregate extends Type {
}
disposed = true;
- Foreign.getInstance().freeAggregate(handle);
+ foreign.freeAggregate(handle);
}
@Override
@@ -74,7 +85,8 @@ public abstract class Aggregate extends Type {
dispose();
}
} catch (Throwable t) {
- t.printStackTrace(System.err);
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Exception when freeing FFI aggregate: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
diff --git a/src/com/kenai/jffi/Array.java b/src/com/kenai/jffi/Array.java
index 520c1c6..3061ed2 100644
--- a/src/com/kenai/jffi/Array.java
+++ b/src/com/kenai/jffi/Array.java
@@ -33,7 +33,7 @@ public final class Array extends Aggregate {
* @param fields The fields contained in the struct.
*/
public Array(Type elementType, int length) {
- super(Foreign.getInstance().newArray(elementType.handle(), length));
+ super(Foreign.getInstance(), Foreign.getInstance().newArray(elementType.handle(), length));
this.elementType = elementType;
this.length = length;
}
diff --git a/src/com/kenai/jffi/CallContext.java b/src/com/kenai/jffi/CallContext.java
index 8c0de65..bb48632 100644
--- a/src/com/kenai/jffi/CallContext.java
+++ b/src/com/kenai/jffi/CallContext.java
@@ -18,6 +18,9 @@
package com.kenai.jffi;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
/**
* Native function call context
*
@@ -43,6 +46,9 @@ public final class CallContext implements CallInfo {
/** The parameter types of this function */
private final Type[] parameterTypes;
+ /** A handle to the foreign interface to keep it alive as long as this object is alive */
+ private final Foreign foreign = Foreign.getInstance();
+
/**
* Creates a new instance of <tt>Function</tt> with default calling convention.
*
@@ -83,7 +89,7 @@ public final class CallContext implements CallInfo {
final int flags = (!saveErrno ? Foreign.F_NOERRNO : 0)
| (convention == CallingConvention.STDCALL ? Foreign.F_STDCALL : Foreign.F_DEFAULT);
- final long h = Foreign.getInstance().newCallContext(returnType.handle(),
+ final long h = foreign.newCallContext(returnType.handle(),
Type.nativeHandles(paramTypes), flags);
if (h == 0) {
throw new RuntimeException("Failed to create native function");
@@ -98,7 +104,7 @@ public final class CallContext implements CallInfo {
this.parameterTypes = (Type[]) paramTypes.clone();
this.parameterCount = paramTypes.length;
- this.rawParameterSize = Foreign.getInstance().getFunctionRawParameterSize(h);
+ this.rawParameterSize = foreign.getFunctionRawParameterSize(h);
}
/**
@@ -152,7 +158,7 @@ public final class CallContext implements CallInfo {
if (disposed) {
throw new RuntimeException("context already freed");
}
- Foreign.getInstance().freeCallContext(contextAddress);
+ foreign.freeCallContext(contextAddress);
disposed = true;
}
@@ -160,10 +166,11 @@ public final class CallContext implements CallInfo {
protected void finalize() throws Throwable {
try {
if (contextAddress != 0 && !disposed) {
- Foreign.getInstance().freeCallContext(contextAddress);
+ foreign.freeCallContext(contextAddress);
}
} catch (Throwable t) {
- t.printStackTrace(System.err);
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Exception when freeing CallContext: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
diff --git a/src/com/kenai/jffi/ClosurePool.java b/src/com/kenai/jffi/ClosurePool.java
index f71e83d..dc45d47 100644
--- a/src/com/kenai/jffi/ClosurePool.java
+++ b/src/com/kenai/jffi/ClosurePool.java
@@ -31,6 +31,7 @@ final class ClosurePool {
private final List<MagazineHolder> partial = new LinkedList<MagazineHolder>();
private final List<MagazineHolder> full = new LinkedList<MagazineHolder>();
private final Set<Magazine> magazines = new HashSet<Magazine>();
+
//
// Since the CallContext native handle is used by the native pool code
// a strong reference to the call context needs to be kept.
@@ -138,6 +139,8 @@ final class ClosurePool {
private static final class Magazine {
/** Store a reference to the MemoryIO accessor here for easy access */
private static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
+ /** A handle to the foreign interface to keep it alive as long as this object is alive */
+ private final Foreign foreign = Foreign.getInstance();
private final CallContext ctx;
private final long magazine;
@@ -148,7 +151,7 @@ final class ClosurePool {
Magazine(CallContext ctx) {
this.ctx = ctx;
- this.magazine = Foreign.getInstance().newClosureMagazine(ctx.getAddress(), Proxy.METHOD);
+ this.magazine = foreign.newClosureMagazine(ctx.getAddress(), Proxy.METHOD);
}
Slot get() {
@@ -161,7 +164,7 @@ final class ClosurePool {
private Slot newSlot() {
Proxy proxy = new Proxy(ctx);
- long h = Foreign.getInstance().closureMagazineGet(magazine, proxy);
+ long h = foreign.closureMagazineGet(magazine, proxy);
if (h == 0) {
nativeEmpty = true;
return null;
@@ -205,7 +208,7 @@ final class ClosurePool {
}
if (magazine != 0 && release) {
- Foreign.getInstance().freeClosureMagazine(magazine);
+ foreign.freeClosureMagazine(magazine);
}
} finally {
super.finalize();
diff --git a/src/com/kenai/jffi/Function.java b/src/com/kenai/jffi/Function.java
index d09e90c..1cfcea4 100644
--- a/src/com/kenai/jffi/Function.java
+++ b/src/com/kenai/jffi/Function.java
@@ -18,6 +18,9 @@
package com.kenai.jffi;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
/**
* Native function invocation context
*
@@ -46,6 +49,9 @@ public final class Function implements CallInfo {
/** Whether the native context has been freed yet */
private volatile boolean disposed = false;
+ /** A handle to the foreign interface to keep it alive as long as this object is alive */
+ private final Foreign foreign = Foreign.getInstance();
+
/**
* Creates a new instance of <tt>Function</tt> with default calling convention.
*
@@ -87,7 +93,7 @@ public final class Function implements CallInfo {
final int flags = (!saveErrno ? Foreign.F_NOERRNO : 0)
| (convention == CallingConvention.STDCALL ? Foreign.F_STDCALL : Foreign.F_DEFAULT);
- final long h = Foreign.getInstance().newFunction(address,
+ final long h = foreign.newFunction(address,
returnType.handle(), Type.nativeHandles(paramTypes),
flags);
if (h == 0) {
@@ -103,7 +109,7 @@ public final class Function implements CallInfo {
this.paramTypes = (Type[]) paramTypes.clone();
this.parameterCount = paramTypes.length;
- this.rawParameterSize = Foreign.getInstance().getFunctionRawParameterSize(h);
+ this.rawParameterSize = foreign.getFunctionRawParameterSize(h);
}
/**
@@ -166,7 +172,7 @@ public final class Function implements CallInfo {
if (disposed) {
throw new RuntimeException("function already freed");
}
- Foreign.getInstance().freeFunction(contextAddress);
+ foreign.freeFunction(contextAddress);
disposed = true;
}
@@ -174,10 +180,11 @@ public final class Function implements CallInfo {
protected void finalize() throws Throwable {
try {
if (contextAddress != 0 && !disposed) {
- Foreign.getInstance().freeFunction(contextAddress);
+ foreign.freeFunction(contextAddress);
}
} catch (Throwable t) {
- t.printStackTrace(System.err);
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Exception when freeing function context: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
diff --git a/src/com/kenai/jffi/LastError.java b/src/com/kenai/jffi/LastError.java
index 9687999..f49bfb1 100644
--- a/src/com/kenai/jffi/LastError.java
+++ b/src/com/kenai/jffi/LastError.java
@@ -22,6 +22,7 @@ package com.kenai.jffi;
* Provides access to the value of errno on unix, or GetLastError on windows.
*/
public final class LastError {
+ private final Foreign foreign = Foreign.getInstance();
/** Lazy-initialization singleton holder */
private static final class SingletonHolder {
@@ -47,7 +48,7 @@ public final class LastError {
*/
@Deprecated
public final int getError() {
- return Foreign.getInstance().getLastError();
+ return foreign.getLastError();
}
/**
@@ -56,7 +57,7 @@ public final class LastError {
* @return The value of errno/GetLastError()
*/
public final int get() {
- return Foreign.getInstance().getLastError();
+ return foreign.getLastError();
}
/**
@@ -65,6 +66,6 @@ public final class LastError {
* @param value The value to set errno to.
*/
public final void set(int value) {
- Foreign.getInstance().setLastError(value);
+ foreign.setLastError(value);
}
}
diff --git a/src/com/kenai/jffi/Library.java b/src/com/kenai/jffi/Library.java
index a6d292d..b57d5b5 100644
--- a/src/com/kenai/jffi/Library.java
+++ b/src/com/kenai/jffi/Library.java
@@ -37,7 +37,7 @@ public final class Library {
/** A handle to the current process */
private static final class DefaultLibrary {
- private static final Library INSTANCE = new Library(null, dlopen(null, LAZY | GLOBAL));
+ private static final Library INSTANCE = openLibrary(null, LAZY | GLOBAL);
}
/** Perform lazy binding. Only resolve symbols as needed */
@@ -46,7 +46,7 @@ public final class Library {
/** Resolve all symbols when loading the library */
public static final int NOW = Foreign.RTLD_NOW;
- /** Symbols in this library are not made availabl to other libraries */
+ /** Symbols in this library are not made available to other libraries */
public static final int LOCAL = Foreign.RTLD_LOCAL;
/** All symbols in the library are made available to other libraries */
@@ -58,6 +58,9 @@ public final class Library {
/** The name of this <tt>Library</tt> */
private final String name;
+ /** A handle to the foreign interface to keep it alive as long as this object is alive */
+ private final Foreign foreign;
+
/**
* Internal wrapper around dlopen.
*
@@ -68,8 +71,7 @@ public final class Library {
* @param flags The flags to pass to dlopen
* @return The native handle for the opened library, or 0 if it failed to open.
*/
- private static final long dlopen(String name, int flags) {
- final Foreign foreign = Foreign.getInstance();
+ private static long dlopen(Foreign foreign, String name, int flags) {
try {
return foreign.dlopen(name, flags);
@@ -132,12 +134,14 @@ public final class Library {
flags = LAZY | LOCAL;
}
- final long address = dlopen(name, flags);
+ final Foreign foreign = Foreign.getInstance();
+ final long address = dlopen(foreign, name, flags);
- return address != 0L ? new Library(name, address) : null;
+ return address != 0L ? new Library(foreign, name, address) : null;
}
- private Library(String name, long address) {
+ private Library(Foreign foreign, String name, long address) {
+ this.foreign = foreign;
this.name = name;
this.handle = address;
}
@@ -149,7 +153,6 @@ public final class Library {
* @return The address of the symbol within the current address space.
*/
public final long getSymbolAddress(String name) {
- final Foreign foreign = Foreign.getInstance();
try {
return foreign.dlsym(handle, name);
@@ -173,7 +176,7 @@ public final class Library {
protected void finalize() throws Throwable {
try {
if (handle != 0L) {
- Foreign.getInstance().dlclose(handle);
+ foreign.dlclose(handle);
}
} finally {
super.finalize();
diff --git a/src/com/kenai/jffi/MemoryIO.java b/src/com/kenai/jffi/MemoryIO.java
index 33b64cf..15c9e56 100644
--- a/src/com/kenai/jffi/MemoryIO.java
+++ b/src/com/kenai/jffi/MemoryIO.java
@@ -26,7 +26,7 @@ import java.lang.reflect.Method;
*/
public abstract class MemoryIO {
/** A handle to the JNI accessor */
- private final Foreign foreign = Foreign.getInstance();
+ final Foreign foreign = Foreign.getInstance();
/** The address mask used to truncate 32bit addresses contained in long values */
private static final long ADDRESS_MASK = Platform.getPlatform().addressMask();
@@ -590,7 +590,7 @@ public abstract class MemoryIO {
* An implementation of MemoryIO using JNI methods.
*/
private static abstract class NativeImpl extends MemoryIO {
- protected static final Foreign foreign = Foreign.getInstance();
+
public final byte getByte(long address) {
return foreign.getByte(address);
}
diff --git a/src/com/kenai/jffi/PageManager.java b/src/com/kenai/jffi/PageManager.java
index f8230e0..e7208b9 100644
--- a/src/com/kenai/jffi/PageManager.java
+++ b/src/com/kenai/jffi/PageManager.java
@@ -31,6 +31,12 @@ abstract public class PageManager {
/** The memory should be writable */
public static final int PROT_WRITE = Foreign.PROT_WRITE;
+ private final Foreign foreign = Foreign.getInstance();
+
+ final Foreign getForeign() {
+ return foreign;
+ }
+
private static final class SingletonHolder {
public static final PageManager INSTANCE = Platform.getPlatform().getOS() == Platform.OS.WINDOWS
? new Windows() : new Unix();
@@ -51,7 +57,7 @@ abstract public class PageManager {
* @return The size of a page on the current system, in bytes.
*/
public final long pageSize() {
- return Foreign.getInstance().pageSize();
+ return getForeign().pageSize();
}
/**
@@ -90,19 +96,19 @@ abstract public class PageManager {
@Override
public long allocatePages(int npages, int protection) {
long sz = npages * pageSize();
- return Foreign.getInstance().mmap(0, sz, protection,
+ return getForeign().mmap(0, sz, protection,
Foreign.MAP_ANON | Foreign.MAP_PRIVATE, -1, 0);
}
@Override
public void freePages(long address, int npages) {
- Foreign.getInstance().munmap(address, npages * pageSize());
+ getForeign().munmap(address, npages * pageSize());
}
@Override
public void protectPages(long address, int npages, int protection) {
- Foreign.getInstance().mprotect(address, npages * pageSize(), protection);
+ getForeign().mprotect(address, npages * pageSize(), protection);
}
}
diff --git a/src/com/kenai/jffi/Struct.java b/src/com/kenai/jffi/Struct.java
index cc6dc53..e44dc4c 100644
--- a/src/com/kenai/jffi/Struct.java
+++ b/src/com/kenai/jffi/Struct.java
@@ -31,7 +31,7 @@ public final class Struct extends Aggregate {
* @param fields The fields contained in the struct.
*/
public Struct(Type... fields) {
- super(Foreign.getInstance().newStruct(Type.nativeHandles(fields), false));
+ super(Foreign.getInstance(), Foreign.getInstance().newStruct(Type.nativeHandles(fields), false));
this.fields = (Type[]) fields.clone();
}
}
diff --git a/src/com/kenai/jffi/Union.java b/src/com/kenai/jffi/Union.java
index bbe7eea..c531c3f 100644
--- a/src/com/kenai/jffi/Union.java
+++ b/src/com/kenai/jffi/Union.java
@@ -31,7 +31,7 @@ public final class Union extends Aggregate {
* @param fields The fields contained in the struct.
*/
public Union(Type... fields) {
- super(Foreign.getInstance().newStruct(Type.nativeHandles(fields), true));
+ super(Foreign.getInstance(), Foreign.getInstance().newStruct(Type.nativeHandles(fields), true));
this.fields = (Type[]) fields.clone();
}
}
--
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