diff --git a/hal/src/main/native/athena/Interrupts.cpp b/hal/src/main/native/athena/Interrupts.cpp index 0899260302..b0b2071abb 100644 --- a/hal/src/main/native/athena/Interrupts.cpp +++ b/hal/src/main/native/athena/Interrupts.cpp @@ -118,7 +118,7 @@ void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, if (anInterrupt == nullptr) { return nullptr; } - anInterrupt->manager->enable(status); + anInterrupt->manager->disable(status); void* param = anInterrupt->param; return param; } diff --git a/wpilibc/src/main/native/cpp/InterruptableSensorBase.cpp b/wpilibc/src/main/native/cpp/InterruptableSensorBase.cpp index 6805eb6615..0bc8c33749 100644 --- a/wpilibc/src/main/native/cpp/InterruptableSensorBase.cpp +++ b/wpilibc/src/main/native/cpp/InterruptableSensorBase.cpp @@ -17,25 +17,26 @@ using namespace frc; InterruptableSensorBase::~InterruptableSensorBase() { if (m_interrupt == HAL_kInvalidHandle) return; int32_t status = 0; - auto param = HAL_CleanInterrupts(m_interrupt, &status); - if (param) { - delete reinterpret_cast(param); - } + HAL_CleanInterrupts(m_interrupt, &status); // Ignore status, as an invalid handle just needs to be ignored. - m_interrupt = HAL_kInvalidHandle; } InterruptableSensorBase::InterruptableSensorBase(InterruptableSensorBase&& rhs) : ErrorBase(std::move(rhs)), - m_interrupt(rhs.m_interrupt.exchange(HAL_kInvalidHandle)) { + m_interrupt(rhs.m_interrupt), + m_interruptHandler{std::move(rhs.m_interruptHandler)} { rhs.m_interrupt = HAL_kInvalidHandle; + rhs.m_interruptHandler = nullptr; } InterruptableSensorBase& InterruptableSensorBase::operator=( InterruptableSensorBase&& rhs) { ErrorBase::operator=(std::move(rhs)); - m_interrupt = rhs.m_interrupt.exchange(HAL_kInvalidHandle); + m_interrupt = rhs.m_interrupt; + m_interruptHandler = std::move(rhs.m_interruptHandler); + rhs.m_interrupt = HAL_kInvalidHandle; + rhs.m_interruptHandler = nullptr; return *this; } @@ -65,7 +66,8 @@ void InterruptableSensorBase::RequestInterrupts(InterruptEventHandler handler) { AllocateInterrupts(false); if (StatusIsFatal()) return; // if allocate failed, out of interrupts - auto handlerPtr = new InterruptEventHandler(std::move(handler)); + m_interruptHandler = + std::make_unique(std::move(handler)); int32_t status = 0; HAL_RequestInterrupts( @@ -86,7 +88,7 @@ void InterruptableSensorBase::RequestInterrupts(InterruptEventHandler handler) { WaitResult res = static_cast(falling | rising); (*self)(res); }, - handlerPtr, &status); + m_interruptHandler.get(), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } @@ -110,12 +112,10 @@ void InterruptableSensorBase::CancelInterrupts() { if (StatusIsFatal()) return; wpi_assert(m_interrupt != HAL_kInvalidHandle); int32_t status = 0; - auto param = HAL_CleanInterrupts(m_interrupt, &status); - if (param) { - delete reinterpret_cast(param); - } + HAL_CleanInterrupts(m_interrupt, &status); // Ignore status, as an invalid handle just needs to be ignored. m_interrupt = HAL_kInvalidHandle; + m_interruptHandler = nullptr; } InterruptableSensorBase::WaitResult InterruptableSensorBase::WaitForInterrupt( diff --git a/wpilibc/src/main/native/include/frc/InterruptableSensorBase.h b/wpilibc/src/main/native/include/frc/InterruptableSensorBase.h index 968587b223..f650b85548 100644 --- a/wpilibc/src/main/native/include/frc/InterruptableSensorBase.h +++ b/wpilibc/src/main/native/include/frc/InterruptableSensorBase.h @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include @@ -144,8 +144,8 @@ class InterruptableSensorBase : public ErrorBase, public SendableBase { virtual void SetUpSourceEdge(bool risingEdge, bool fallingEdge); protected: - // atomic for proper destruction - std::atomic m_interrupt{HAL_kInvalidHandle}; + HAL_InterruptHandle m_interrupt{HAL_kInvalidHandle}; + std::unique_ptr m_interruptHandler{nullptr}; void AllocateInterrupts(bool watcher); };