Skip to content

Commit

Permalink
Merge pull request #152 from Tianscar/master
Browse files Browse the repository at this point in the history
Use cleaner instead of finalize
  • Loading branch information
headius committed Feb 9, 2024
2 parents 8ebace3 + 808b051 commit 2e7c865
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 100 deletions.
33 changes: 19 additions & 14 deletions src/main/java/com/kenai/jffi/Aggregate.java
Expand Up @@ -32,11 +32,14 @@

package com.kenai.jffi;

import com.kenai.jffi.internal.Cleaner;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.logging.Logger;

public abstract class Aggregate extends Type {

private final TypeInfo typeInfo;
private final long handle;
private volatile int disposed;
Expand All @@ -54,26 +57,28 @@ public abstract class Aggregate extends Type {
this.foreign = foreign;
this.handle = handle;
this.typeInfo = new TypeInfo(handle, foreign.getTypeType(handle), foreign.getTypeSize(handle), foreign.getTypeAlign(handle));

Cleaner.register(this, new Runnable() {
@Override
public void run() {
try {
int disposed = UPDATER.getAndSet(Aggregate.this, 1);
if (disposed == 0) {
foreign.freeAggregate(typeInfo.handle);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"Exception when freeing FFI aggregate: %s", t.getLocalizedMessage());
}
}
});
}

final TypeInfo getTypeInfo() {
return typeInfo;
}

@Deprecated
public synchronized final void dispose() {}

@Override
protected void finalize() throws Throwable {
try {
int disposed = UPDATER.getAndSet(this, 1);
if (disposed == 0) {
foreign.freeAggregate(typeInfo.handle);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"Exception when freeing FFI aggregate: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
}
}
32 changes: 18 additions & 14 deletions src/main/java/com/kenai/jffi/CallContext.java
Expand Up @@ -32,6 +32,8 @@

package com.kenai.jffi;

import com.kenai.jffi.internal.Cleaner;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
Expand All @@ -44,6 +46,7 @@
* native function, or to implement a callback from native code to java.
*/
public final class CallContext {

/** The native address of the context */
final long contextAddress;

Expand Down Expand Up @@ -160,6 +163,21 @@ public CallContext(Type returnType, Type[] parameterTypes, CallingConvention con
this.rawParameterSize = foreign.getCallContextRawParameterSize(h);
this.parameterTypeHandles = Type.nativeHandles(parameterTypes);
this.flags = flags;

Cleaner.register(this, new Runnable() {
@Override
public void run() {
try {
int disposed = UPDATER.getAndSet(CallContext.this, 1);
if (disposed == 0 && contextAddress != 0) {
foreign.freeCallContext(contextAddress);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"exception when freeing " + getClass() + ": %s", t.getLocalizedMessage());
}
}
});
}

/**
Expand Down Expand Up @@ -237,18 +255,4 @@ public int hashCode() {
@Deprecated
public final void dispose() {}

@Override
protected void finalize() throws Throwable {
try {
int disposed = UPDATER.getAndSet(this, 1);
if (disposed == 0 && contextAddress != 0) {
foreign.freeCallContext(contextAddress);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"exception when freeing " + getClass() + ": %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
}
}
34 changes: 18 additions & 16 deletions src/main/java/com/kenai/jffi/ClosureMagazine.java
@@ -1,6 +1,7 @@
package com.kenai.jffi;

import java.util.concurrent.atomic.AtomicBoolean;
import com.kenai.jffi.internal.Cleaner;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand All @@ -9,6 +10,7 @@
*
*/
public final class ClosureMagazine {

/** A handle to the foreign interface to keep it alive as long as this object is alive */
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
private final Foreign foreign;
Expand All @@ -23,6 +25,21 @@ public final class ClosureMagazine {
this.foreign = foreign;
this.callContext = callContext;
this.magazineAddress = magazineAddress;

Cleaner.register(this, new Runnable() {
@Override
public void run() {
try {
int disposed = UPDATER.getAndSet(ClosureMagazine.this, 1);
if (magazineAddress != 0L && disposed == 0) {
foreign.freeClosureMagazine(magazineAddress);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"exception when freeing " + getClass() + ": %s", t.getLocalizedMessage());
}
}
});
}

public Closure.Handle allocate(Object proxy) {
Expand Down Expand Up @@ -60,19 +77,4 @@ public void dispose() { }
public void free() {}
}

@Override
protected void finalize() throws Throwable {
try {
int disposed = UPDATER.getAndSet(this, 1);
if (magazineAddress != 0L && disposed == 0) {
foreign.freeClosureMagazine(magazineAddress);
}
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"exception when freeing " + getClass() + ": %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
}

}
63 changes: 32 additions & 31 deletions src/main/java/com/kenai/jffi/ClosurePool.java
Expand Up @@ -32,6 +32,8 @@

package com.kenai.jffi;

import com.kenai.jffi.internal.Cleaner;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
Expand Down Expand Up @@ -193,6 +195,27 @@ private static final class Magazine {
slots.toArray(this.slots);
next = 0;
freeCount = this.slots.length;

Cleaner.register(this, new Runnable() {
@Override
public void run() {
boolean release = true;
//
// If any of the closures allocated from this magazine set autorelease=false
// then this magazine cannot be freed, so just let it leak
//
for (int i = 0; i < Magazine.this.slots.length; i++) {
if (!Magazine.this.slots[i].autorelease) {
release = false;
break;
}
}

if (magazine != 0 && release) {
foreign.freeClosureMagazine(magazine);
}
}
});
}

Slot get() {
Expand Down Expand Up @@ -225,29 +248,6 @@ void recycle() {
next = 0;
}

@Override
protected void finalize() throws Throwable {
try {
boolean release = true;
//
// If any of the closures allocated from this magazine set autorelease=false
// then this magazine cannot be freed, so just let it leak
//
for (int i = 0; i < slots.length; i++) {
if (!slots[i].autorelease) {
release = false;
break;
}
}

if (magazine != 0 && release) {
foreign.freeClosureMagazine(magazine);
}
} finally {
super.finalize();
}
}

static final class Slot {
/**
* The address of the native closure structure.
Expand All @@ -273,22 +273,22 @@ public Slot(long handle, Proxy proxy) {
}

private static final class MagazineHolder {

final ClosurePool pool;
final Magazine magazine;

public MagazineHolder(ClosurePool pool, Magazine magazine) {
this.pool = pool;
this.magazine = magazine;
}

@Override
protected void finalize() throws Throwable {
try {
pool.recycle(magazine);
} finally {
super.finalize();
}
Cleaner.register(this, new Runnable() {
@Override
public void run() {
pool.recycle(magazine);
}
});
}

}

/**
Expand Down Expand Up @@ -339,4 +339,5 @@ public void invoke(long retvalAddress, long paramAddress) {
public void invoke(Buffer buffer) {
}
};

}
24 changes: 12 additions & 12 deletions src/main/java/com/kenai/jffi/Library.java
Expand Up @@ -32,6 +32,8 @@

package com.kenai.jffi;

import com.kenai.jffi.internal.Cleaner;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -164,6 +166,15 @@ private Library(Foreign foreign, String name, long address) {
this.foreign = foreign;
this.name = name;
this.handle = address;
Cleaner.register(this, new Runnable() {
@Override
public void run() {
int disposed = UPDATER.getAndSet(Library.this, 1);
if (disposed == 0 && handle != 0L) {
foreign.dlclose(handle);
}
}
});
}

/**
Expand Down Expand Up @@ -191,16 +202,5 @@ public static final String getLastError() {
String error = lastError.get();
return error != null ? error : "unknown";
}

@Override
protected void finalize() throws Throwable {
try {
int disposed = UPDATER.getAndSet(this, 1);
if (disposed == 0 && handle != 0L) {
foreign.dlclose(handle);
}
} finally {
super.finalize();
}
}

}
28 changes: 15 additions & 13 deletions src/main/java/com/kenai/jffi/NativeMethods.java
Expand Up @@ -32,7 +32,8 @@

package com.kenai.jffi;

import java.util.ArrayList;
import com.kenai.jffi.internal.Cleaner;

import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
Expand Down Expand Up @@ -144,18 +145,19 @@ private static final class ResourceHolder {
public ResourceHolder(MemoryIO mm, long memory) {
this.mm = mm;
this.memory = memory;
}

@Override
protected void finalize() throws Throwable {
try {
mm.freeMemory(memory);
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"Exception when freeing native method struct array: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}

Cleaner.register(this, new Runnable() {
@Override
public void run() {
try {
mm.freeMemory(memory);
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"Exception when freeing native method struct array: %s", t.getLocalizedMessage());
}
}
});
}
}

}

0 comments on commit 2e7c865

Please sign in to comment.