Moves Notifier over to handles (#97)

Internally, the linked list now uses shared_ptrs instead of raw
pointers. In addition, in the WPILib the notifier handle is now made
atomic. Then before the class is destructed, the handle is now set to 0.
This should help solve one of the existing race conditions. A 0 handle
is correctly handled down at the HAL level.
This commit is contained in:
Thad House
2016-06-05 07:29:47 -07:00
committed by Peter Johnson
parent 8527f2c2a1
commit 776a991d61
13 changed files with 197 additions and 176 deletions

View File

@@ -7,6 +7,7 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.wpilibj.hal.NotifierJNI;
@@ -18,7 +19,7 @@ public class Notifier {
private final ReentrantLock m_processLock = new ReentrantLock();
// The C pointer to the notifier object. We don't use it directly, it is
// just passed to the JNI bindings.
private long m_notifier;
AtomicInteger m_notifier = new AtomicInteger();
// The time, in microseconds, at which the corresponding handler should be
// called. Has the same zero as Utility.getFPGATime().
private double m_expirationTime = 0;
@@ -38,13 +39,14 @@ public class Notifier {
public Process(Runnable run) {
m_handler = run;
m_notifier = NotifierJNI.initializeNotifier(this);
m_notifier.set(NotifierJNI.initializeNotifier(this));
}
@Override
@SuppressWarnings("NoFinalizer")
protected void finalize() {
NotifierJNI.cleanNotifier(m_notifier);
int handle = m_notifier.getAndSet(0);
NotifierJNI.cleanNotifier(handle);
m_handlerLock.lock();
}
@@ -52,7 +54,7 @@ public class Notifier {
* Update the alarm hardware to reflect the next alarm.
*/
private void updateAlarm() {
NotifierJNI.updateNotifierAlarm(m_notifier, (long) (m_expirationTime * 1e6));
NotifierJNI.updateNotifierAlarm(m_notifier.get(), (long) (m_expirationTime * 1e6));
}
/**
@@ -84,7 +86,7 @@ public class Notifier {
}
public void stop() {
NotifierJNI.stopNotifierAlarm(m_notifier);
NotifierJNI.stopNotifierAlarm(m_notifier.get());
// Wait for a currently executing handler to complete before returning
// from stop()

View File

@@ -24,20 +24,20 @@ public class NotifierJNI extends JNIWrapper {
/**
* Initializes the notifier.
*/
public static native long initializeNotifier(NotifierJNIHandlerFunction func);
public static native int initializeNotifier(NotifierJNIHandlerFunction func);
/**
* Deletes the notifier object when we are done with it.
*/
public static native void cleanNotifier(long notifierPtr);
public static native void cleanNotifier(int notifierHandle);
/**
* Sets the notifier to call the callback in another triggerTime microseconds.
*/
public static native void updateNotifierAlarm(long notifierPtr, long triggerTime);
public static native void updateNotifierAlarm(int notifierHandle, long triggerTime);
/**
* Tells the notifier to stop calling the callback.
*/
public static native void stopNotifierAlarm(long notifierPtr);
public static native void stopNotifierAlarm(int notifierHandle);
}