mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +00:00
InterruptableSensorBase: Fix callback function deletion (#1807)
Save the callback function into a unique_ptr member instead.
This commit is contained in:
committed by
Peter Johnson
parent
810e58ea85
commit
6411bd79c6
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<InterruptEventHandler*>(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<InterruptEventHandler>(std::move(handler));
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_RequestInterrupts(
|
||||
@@ -86,7 +88,7 @@ void InterruptableSensorBase::RequestInterrupts(InterruptEventHandler handler) {
|
||||
WaitResult res = static_cast<WaitResult>(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<InterruptEventHandler*>(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(
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <hal/Interrupts.h>
|
||||
|
||||
@@ -144,8 +144,8 @@ class InterruptableSensorBase : public ErrorBase, public SendableBase {
|
||||
virtual void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
|
||||
|
||||
protected:
|
||||
// atomic for proper destruction
|
||||
std::atomic<HAL_InterruptHandle> m_interrupt{HAL_kInvalidHandle};
|
||||
HAL_InterruptHandle m_interrupt{HAL_kInvalidHandle};
|
||||
std::unique_ptr<InterruptEventHandler> m_interruptHandler{nullptr};
|
||||
|
||||
void AllocateInterrupts(bool watcher);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user