diff --git a/CMakeLists.txt b/CMakeLists.txt index baae26d..f09c585 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,9 @@ function(export_mpf_lib targetName) install(EXPORT ${targetName}Config DESTINATION lib/cmake/${targetName} EXPORT_LINK_INTERFACE_LIBRARIES) endfunction() +add_subdirectory(internal) +include_directories(internal/include) + add_subdirectory(interface) include_directories(interface/include) diff --git a/detection/api/CMakeLists.txt b/detection/api/CMakeLists.txt index 10c0528..b5ab91a 100644 --- a/detection/api/CMakeLists.txt +++ b/detection/api/CMakeLists.txt @@ -109,12 +109,12 @@ set(SOURCE_FILES ) add_library(mpfDetectionComponentApi SHARED ${SOURCE_FILES}) -target_link_libraries(mpfDetectionComponentApi mpfComponentInterface ${OpenCV_LIBS}) - +target_link_libraries( + mpfDetectionComponentApi + PUBLIC mpfComponentInterface ${OpenCV_LIBS} + PRIVATE mpfInternalObjLib) export_mpf_lib(mpfDetectionComponentApi) - add_subdirectory(test) - diff --git a/detection/api/src/MPFVideoCapture.cpp b/detection/api/src/MPFVideoCapture.cpp index 68c32b9..d53b958 100644 --- a/detection/api/src/MPFVideoCapture.cpp +++ b/detection/api/src/MPFVideoCapture.cpp @@ -36,6 +36,7 @@ #include "IntervalFrameFilter.h" #include "KeyFrameFilter.h" #include "MPFDetectionException.h" +#include "MPFBreaker.h" #include "MPFVideoCapture.h" @@ -207,6 +208,7 @@ namespace MPF { namespace COMPONENT { bool MPFVideoCapture::Read(cv::Mat &frame) { + MPFBreaker::check(); int originalPosBeforeRead = framePosition_; if (frameFilter_->IsPastEndOfSegment(originalPosBeforeRead)) { frame.release(); diff --git a/internal/CMakeLists.txt b/internal/CMakeLists.txt new file mode 100644 index 0000000..893f0d6 --- /dev/null +++ b/internal/CMakeLists.txt @@ -0,0 +1,48 @@ +############################################################################# +# NOTICE # +# # +# This software (or technical data) was produced for the U.S. Government # +# under contract, and is subject to the Rights in Data-General Clause # +# 52.227-14, Alt. IV (DEC 2007). # +# # +# Copyright 2026 The MITRE Corporation. All Rights Reserved. # +############################################################################# + +############################################################################# +# Copyright 2026 The MITRE Corporation # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################# + +cmake_minimum_required(VERSION 3.6) +project(openmpf-internal) + +set(CMAKE_CXX_STANDARD 17) + +include_directories(include) + +set(SOURCE_FILES + include/MPFBreaker.h + src/MPFBreaker.cpp) + +add_library(mpfInternalObjLib OBJECT ${SOURCE_FILES}) + +# Position-independent code is required because MPFBreaker uses a global variable that should be +# shared with any library linking to this one. +set_target_properties(mpfInternalObjLib PROPERTIES + INTERFACE_POSITION_INDEPENDENT_CODE ON + POSITION_INDEPENDENT_CODE ON) + +add_library(mpfInternal SHARED $) + +export_mpf_lib(mpfInternal) diff --git a/internal/include/MPFBreaker.h b/internal/include/MPFBreaker.h new file mode 100644 index 0000000..cb8f8ed --- /dev/null +++ b/internal/include/MPFBreaker.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * NOTICE * + * * + * This software (or technical data) was produced for the U.S. Government * + * under contract, and is subject to the Rights in Data-General Clause * + * 52.227-14, Alt. IV (DEC 2007). * + * * + * Copyright 2026 The MITRE Corporation. All Rights Reserved. * + ******************************************************************************/ + +/****************************************************************************** + * Copyright 2026 The MITRE Corporation * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +#pragma once + +#include + +namespace MPF::COMPONENT { + + class StopRequestedException : public std::runtime_error { + public: + using std::runtime_error::runtime_error; + }; + + + namespace MPFBreaker { + void requestStop(); + + void check(); + } +} // namespace MPF::COMPONENT diff --git a/internal/src/MPFBreaker.cpp b/internal/src/MPFBreaker.cpp new file mode 100644 index 0000000..6160d6d --- /dev/null +++ b/internal/src/MPFBreaker.cpp @@ -0,0 +1,74 @@ +/****************************************************************************** + * NOTICE * + * * + * This software (or technical data) was produced for the U.S. Government * + * under contract, and is subject to the Rights in Data-General Clause * + * 52.227-14, Alt. IV (DEC 2007). * + * * + * Copyright 2026 The MITRE Corporation. All Rights Reserved. * + ******************************************************************************/ + +/****************************************************************************** + * Copyright 2026 The MITRE Corporation * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +#include "MPFBreaker.h" + +#include +#include +#include +#include + +namespace MPF::COMPONENT { + namespace { + std::atomic STOP_REQUESTED{false}; + } + + + void MPFBreaker::requestStop() { + std::cerr << "MPFBreaker: Setting stop requested flag to true.\n"; + STOP_REQUESTED.store(true, std::memory_order::memory_order_release); + } + + + void MPFBreaker::check() { + if (!STOP_REQUESTED.load(std::memory_order::memory_order_acquire)) { + return; + } + + std::cerr << "MPFBreaker: The stop requested flag was set to true. " + "Throwing StopRequestedException.\n"; + auto e_ptr = std::current_exception(); + if (!e_ptr) { + throw StopRequestedException{"Stop requested."}; + } + + try { + std::rethrow_exception(e_ptr); + } + catch (const StopRequestedException&) { + throw; + } + catch (const std::exception& e) { + throw StopRequestedException{ + std::string{"Stop requested. Suppressed the following exception: "} + + e.what()}; + } + catch (...) { + throw StopRequestedException{ + "Stop requested. Suppressed a thrown non-exception object."}; + } + } +} // namespace MPF::COMPONENT