diff --git a/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceAnnouncer.java b/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceAnnouncer.java index 6dff4541b2..9ccb322745 100644 --- a/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceAnnouncer.java +++ b/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceAnnouncer.java @@ -4,11 +4,18 @@ package edu.wpi.first.net; +import edu.wpi.first.util.WPICleaner; +import java.lang.ref.Cleaner.Cleanable; import java.util.Map; /** Class to announce over mDNS that a service is available. */ public class MulticastServiceAnnouncer implements AutoCloseable { private final int m_handle; + private final Cleanable m_cleanable; + + private static Runnable cleanupAction(int handle) { + return () -> WPINetJNI.freeMulticastServiceAnnouncer(handle); + } /** * Creates a MulticastServiceAnnouncer. @@ -24,6 +31,7 @@ public class MulticastServiceAnnouncer implements AutoCloseable { String[] values = txt.values().toArray(String[]::new); m_handle = WPINetJNI.createMulticastServiceAnnouncer(serviceName, serviceType, port, keys, values); + m_cleanable = WPICleaner.register(this, cleanupAction(m_handle)); } /** @@ -36,11 +44,12 @@ public class MulticastServiceAnnouncer implements AutoCloseable { public MulticastServiceAnnouncer(String serviceName, String serviceType, int port) { m_handle = WPINetJNI.createMulticastServiceAnnouncer(serviceName, serviceType, port, null, null); + m_cleanable = WPICleaner.register(this, cleanupAction(m_handle)); } @Override public void close() { - WPINetJNI.freeMulticastServiceAnnouncer(m_handle); + m_cleanable.clean(); } public void start() { diff --git a/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceResolver.java b/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceResolver.java index 2426de29d6..b676f4c2dc 100644 --- a/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceResolver.java +++ b/wpinet/src/main/java/edu/wpi/first/net/MulticastServiceResolver.java @@ -4,9 +4,17 @@ package edu.wpi.first.net; +import edu.wpi.first.util.WPICleaner; +import java.lang.ref.Cleaner.Cleanable; + /** Class to resolve a service over mDNS. */ public class MulticastServiceResolver implements AutoCloseable { private final int m_handle; + private final Cleanable m_cleanable; + + private static Runnable cleanupAction(int handle) { + return () -> WPINetJNI.freeMulticastServiceResolver(handle); + } /** * Creates a MulticastServiceResolver. @@ -15,11 +23,12 @@ public class MulticastServiceResolver implements AutoCloseable { */ public MulticastServiceResolver(String serviceType) { m_handle = WPINetJNI.createMulticastServiceResolver(serviceType); + m_cleanable = WPICleaner.register(this, cleanupAction(m_handle)); } @Override public void close() { - WPINetJNI.freeMulticastServiceResolver(m_handle); + m_cleanable.clean(); } public void start() { diff --git a/wpiutil/src/main/java/edu/wpi/first/util/WPICleaner.java b/wpiutil/src/main/java/edu/wpi/first/util/WPICleaner.java new file mode 100644 index 0000000000..0c497d4368 --- /dev/null +++ b/wpiutil/src/main/java/edu/wpi/first/util/WPICleaner.java @@ -0,0 +1,28 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.util; + +import java.lang.ref.Cleaner; +import java.lang.ref.Cleaner.Cleanable; + +/** Cleaner object for WPILib objects. */ +public final class WPICleaner { + private WPICleaner() { + throw new UnsupportedOperationException("This is a utility class!"); + } + + private static final Cleaner instance = Cleaner.create(); + + /** + * Register an object with the cleaner. + * + * @param object The object to register. + * @param runnable The runnable to call on cleanup. + * @return The registered Cleanable. + */ + public static Cleanable register(Object object, Runnable runnable) { + return instance.register(object, runnable); + } +}