Changes notifier to be closable. (#1090)

Fixes #1089
This commit is contained in:
Thad House
2018-05-24 16:56:29 -07:00
committed by Peter Johnson
parent 40cc743cc7
commit 62d5301b1f
3 changed files with 27 additions and 16 deletions

View File

@@ -12,9 +12,9 @@ import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.wpilibj.hal.NotifierJNI;
public class Notifier {
public class Notifier implements AutoCloseable {
// The thread waiting on the HAL alarm.
private final Thread m_thread;
private Thread m_thread;
// The lock for the process information.
private final ReentrantLock m_processLock = new ReentrantLock();
// The C pointer to the notifier object. We don't use it directly, it is
@@ -35,7 +35,15 @@ public class Notifier {
@Override
@SuppressWarnings("NoFinalizer")
protected void finalize() {
close();
}
@Override
public void close() {
int handle = m_notifier.getAndSet(0);
if (handle == 0) {
return;
}
NotifierJNI.stopNotifier(handle);
// Join the thread to ensure the handler has exited.
if (m_thread.isAlive()) {
@@ -47,6 +55,7 @@ public class Notifier {
}
}
NotifierJNI.cleanNotifier(handle);
m_thread = null;
}
/**
@@ -63,8 +72,8 @@ public class Notifier {
/**
* Create a Notifier for timer event notification.
*
* @param run The handler that is called at the notification time which is set using StartSingle
* or StartPeriodic.
* @param run The handler that is called at the notification time which is set
* using StartSingle or StartPeriodic.
*/
public Notifier(Runnable run) {
m_handler = run;
@@ -98,6 +107,7 @@ public class Notifier {
}
}
});
m_thread.setName("Notifier");
m_thread.setDaemon(true);
m_thread.setUncaughtExceptionHandler((thread, error) -> {
Throwable cause = error.getCause();
@@ -127,8 +137,8 @@ public class Notifier {
}
/**
* Register for single event notification. A timer event is queued for a single event after the
* specified delay.
* Register for single event notification. A timer event is queued for a single
* event after the specified delay.
*
* @param delay Seconds to wait before the handler is called.
*/
@@ -145,12 +155,12 @@ public class Notifier {
}
/**
* Register for periodic event notification. A timer event is queued for periodic event
* notification. Each time the interrupt occurs, the event will be immediately requeued for the
* same time interval.
* Register for periodic event notification. A timer event is queued for
* periodic event notification. Each time the interrupt occurs, the event will
* be immediately requeued for the same time interval.
*
* @param period Period in seconds to call the handler starting one period after the call to this
* method.
* @param period Period in seconds to call the handler starting one period after
* the call to this method.
*/
public void startPeriodic(double period) {
m_processLock.lock();
@@ -165,9 +175,10 @@ public class Notifier {
}
/**
* Stop timer events from occurring. Stop any repeating timer events from occurring. This will
* also remove any single notification events from the queue. If a timer-based call to the
* registered handler is in progress, this function will block until the handler call is complete.
* Stop timer events from occurring. Stop any repeating timer events from
* occurring. This will also remove any single notification events from the
* queue. If a timer-based call to the registered handler is in progress, this
* function will block until the handler call is complete.
*/
public void stop() {
NotifierJNI.cancelNotifierAlarm(m_notifier.get());

View File

@@ -91,7 +91,7 @@ public class PIDController extends PIDBase implements Controller {
@Override
public void close() {
super.close();
m_controlLoop.stop();
m_controlLoop.close();
m_thisMutex.lock();
try {
m_pidOutput = null;

View File

@@ -438,7 +438,7 @@ public class SPI implements AutoCloseable {
@Override
public void close() {
m_notifier.stop();
m_notifier.close();
}
final Notifier m_notifier;