#pragma once #include "camera_pipeline.hpp" #include #include #include #include #include namespace cms { // Construct before starting workers so all threads inherit the signal mask. // Stop requests run in an ordinary thread, never an asynchronous signal handler. class StopSignals { public: explicit StopSignals(CameraPipeline& pipeline):pipeline_(pipeline) { sigemptyset(&signals_);sigaddset(&signals_,SIGINT);sigaddset(&signals_,SIGTERM); if(pthread_sigmask(SIG_BLOCK,&signals_,&old_)!=0)throw std::runtime_error("Cannot block termination signals"); try { thread_=std::thread([this]{ while(!done_) { timespec timeout{0,100000000}; int signal=sigtimedwait(&signals_,nullptr,&timeout); if(signal==SIGINT||signal==SIGTERM){pipeline_.requestStop();break;} } }); }catch(...){pthread_sigmask(SIG_SETMASK,&old_,nullptr);throw;} } ~StopSignals(){done_=true;if(thread_.joinable())thread_.join();pthread_sigmask(SIG_SETMASK,&old_,nullptr);} StopSignals(StopSignals const&)=delete; StopSignals& operator=(StopSignals const&)=delete; private: CameraPipeline& pipeline_; sigset_t signals_{},old_{}; std::atomic done_{false}; std::thread thread_; }; }