diff --git a/codegen/lib/templates/java/class.erb b/codegen/lib/templates/java/class.erb index a10c6008ecb..3b49d35a49d 100644 --- a/codegen/lib/templates/java/class.erb +++ b/codegen/lib/templates/java/class.erb @@ -1,5 +1,5 @@ import java.security.InvalidParameterException; -import java.util.HashSet; +import wallet.core.java.GenericPhantomReference; <% less = entity.static_methods.detect{ |i| i.name == 'Less' } -%> <% equal = entity.static_methods.detect{ |i| i.name == 'Equal' } -%> @@ -21,7 +21,7 @@ public final class <%= entity.name %> { <%= entity.name %> instance = new <%= entity.name %>(); instance.nativeHandle = nativeHandle; <% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%> - <%= entity.name %>PhantomReference.register(instance, nativeHandle); + GenericPhantomReference.register(instance, nativeHandle, <%= entity.name %>::nativeDelete); <% end -%> return instance; } @@ -96,9 +96,7 @@ public final class <%= entity.name %> { throw new InvalidParameterException(); } - GenericPhantomReference.register(someObject, someHandle, handle -> { - nativeDelete(nativeHandle); - }); + GenericPhantomReference.register(this, nativeHandle, <%= entity.name %>::nativeDelete); } <%- end -%> diff --git a/jni/java/wallet/core/java/GenericPhantomReference.java b/jni/java/wallet/core/java/GenericPhantomReference.java new file mode 100644 index 00000000000..1c5ee46dc76 --- /dev/null +++ b/jni/java/wallet/core/java/GenericPhantomReference.java @@ -0,0 +1,51 @@ +package wallet.core.java; + +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; +import java.util.Set; +import java.util.HashSet; + +public class GenericPhantomReference extends PhantomReference { + private final long nativeHandle; + private final OnDeleteCallback onDeleteCallback; + + private static final Set references = new HashSet<>(); + private static final ReferenceQueue queue = new ReferenceQueue<>(); + + static { + Thread finalizingDaemon = new Thread(() -> { + try { + doDeletes(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + finalizingDaemon.setName("WCFinalizingDaemon"); + finalizingDaemon.setDaemon(true); + finalizingDaemon.setPriority(Thread.NORM_PRIORITY); + finalizingDaemon.start(); + } + + private GenericPhantomReference(Object referent, long handle, OnDeleteCallback onDelete) { + super(referent, queue); + this.nativeHandle = handle; + this.onDeleteCallback = onDelete; + } + + public static void register(Object referent, long handle, OnDeleteCallback onDelete) { + references.add(new GenericPhantomReference(referent, handle, onDelete)); + } + + private static void doDeletes() throws InterruptedException { + GenericPhantomReference ref = (GenericPhantomReference) queue.remove(); + for (; ref != null; ref = (GenericPhantomReference) queue.remove()) { + ref.onDeleteCallback.nativeDelete(ref.nativeHandle); + references.remove(ref); + } + } + + @FunctionalInterface + public interface OnDeleteCallback { + void nativeDelete(long handle); + } +} diff --git a/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/WalletCoreLibLoader.kt b/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/WalletCoreLibLoader.kt index 23c20a24897..7c2b43eed0e 100644 --- a/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/WalletCoreLibLoader.kt +++ b/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/WalletCoreLibLoader.kt @@ -34,9 +34,9 @@ object WalletCoreLibLoader { } private fun getLibResourcePath(): String { - val osNameOriginal = System.getProperty("os.name").lowercase() + val osNameOriginal = System.getProperty("os.name")!!.lowercase() val osName = osNameOriginal.lowercase() - val archOriginal = System.getProperty("os.arch").lowercase() + val archOriginal = System.getProperty("os.arch")!!.lowercase() val arch = archOriginal.lowercase() return when {