cscore: Change impl to only one singleton (#1398)

This avoids a number of shutdown use-after-free races by controlling the
destruction order.  It also is a prerequisite to making the internal
interfaces mockable for unit testing.
This commit is contained in:
Peter Johnson
2018-10-31 20:22:58 -07:00
committed by GitHub
parent 1dec0393a1
commit e27d6d7bb8
28 changed files with 433 additions and 356 deletions

View File

@@ -13,6 +13,7 @@
#include <wpi/SmallString.h>
#include "Handle.h"
#include "Instance.h"
#include "Log.h"
#include "Notifier.h"
#include "c_util.h"
@@ -20,14 +21,17 @@
using namespace cs;
CvSinkImpl::CvSinkImpl(const wpi::Twine& name) : SinkImpl{name} {
CvSinkImpl::CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger,
Notifier& notifier, Telemetry& telemetry)
: SinkImpl{name, logger, notifier, telemetry} {
m_active = true;
// m_thread = std::thread(&CvSinkImpl::ThreadMain, this);
}
CvSinkImpl::CvSinkImpl(const wpi::Twine& name,
CvSinkImpl::CvSinkImpl(const wpi::Twine& name, wpi::Logger& logger,
Notifier& notifier, Telemetry& telemetry,
std::function<void(uint64_t time)> processFrame)
: SinkImpl{name} {}
: SinkImpl{name, logger, notifier, telemetry} {}
CvSinkImpl::~CvSinkImpl() { Stop(); }
@@ -119,24 +123,28 @@ void CvSinkImpl::ThreadMain() {
namespace cs {
CS_Sink CreateCvSink(const wpi::Twine& name, CS_Status* status) {
auto sink = std::make_shared<CvSinkImpl>(name);
auto handle = Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
Notifier::GetInstance().NotifySink(name, handle, CS_SINK_CREATED);
auto& inst = Instance::GetInstance();
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry);
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
return handle;
}
CS_Sink CreateCvSinkCallback(const wpi::Twine& name,
std::function<void(uint64_t time)> processFrame,
CS_Status* status) {
auto sink = std::make_shared<CvSinkImpl>(name, processFrame);
auto handle = Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
Notifier::GetInstance().NotifySink(name, handle, CS_SINK_CREATED);
auto& inst = Instance::GetInstance();
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry, processFrame);
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
return handle;
}
void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -145,7 +153,7 @@ void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
}
uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -155,7 +163,7 @@ uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -164,7 +172,7 @@ uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
}
std::string GetSinkError(CS_Sink sink, CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -174,7 +182,7 @@ std::string GetSinkError(CS_Sink sink, CS_Status* status) {
wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -183,7 +191,7 @@ wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
}
void SetSinkEnabled(CS_Sink sink, bool enabled, CS_Status* status) {
auto data = Sinks::GetInstance().Get(sink);
auto data = Instance::GetInstance().sinks.Get(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return;