diff --git a/include/CAcquisition.h b/include/CAcquisition.h index 234cfda50d9d8a919e2cfdd94804e4847a49cd70..ad5e4eee0b9bed1f1a1d022c87f3a025d4d6a607 100644 --- a/include/CAcquisition.h +++ b/include/CAcquisition.h @@ -21,6 +21,7 @@ #include #include +#include #include #include "CAcquisitionBuffer.h" @@ -75,6 +76,14 @@ public: */ virtual ~CAcquisition(); + /** + * configure lockFile for the acquisition thread + * @param[in] lockFile lock file path + * @details the lock will be held when acquisition thread is running + * @details use an empty string to disable the feature + */ + void setLockFile(const std::string &lockFile); + /** * Start the acquisition threads */ @@ -175,6 +184,7 @@ private: std::mutex startMutex_; std::condition_variable startCV_; bool startAcquisition_; + std::shared_ptr lockFile_; }; /** diff --git a/include/CDaq.h b/include/CDaq.h index 7e27a60a17361fe74e883421f8d39d21a53ccce8..30afa00a421a5205c4f296d562d6a822e404609e 100644 --- a/include/CDaq.h +++ b/include/CDaq.h @@ -122,8 +122,9 @@ public: void InitServiceDim(); /** * Initialize acquisition and writer threads + * @param[in] lockFile advisory lock for writer and acquisition threads */ - void InitializeThreads(); + void InitializeThreads(const std::string &lockFile = std::string()); /** * Update card's configuration after the reception of valid parameters through * DIM service diff --git a/include/CWriter.h b/include/CWriter.h index 9fff89693eb9a87f6749000e4dcd122036e765fe..56e6703dc554354156eeb1948dae3368e0afff4f 100644 --- a/include/CWriter.h +++ b/include/CWriter.h @@ -16,6 +16,7 @@ #include +#include #include #include @@ -72,6 +73,14 @@ public: */ virtual ~CWriter(); + /** + * configure lockFile for the writer thread + * @param[in] lockFile lock file path + * @details the lock will be held when writer thread is running + * @details use an empty string to disable the feature + */ + void setLockFile(const std::string &lockFile); + /** * Start the writer thread */ @@ -265,6 +274,7 @@ private: acqc acqcHeader_; std::vector zsMasterList_; ntof::ZeroSuppression::zsMode zsMode_; + std::shared_ptr lockFile_; }; /** diff --git a/include/typedefs.h b/include/typedefs.h index d7662c1696fc10eec271e2101ad778ba0bb07801..5da8c28c0eb73e6f9da7e143b379e862e17b9ea3 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -39,6 +39,7 @@ typedef struct int nbVirtualCards; int acqPoolSize; bool spdLogTrace; + std::string lockFile; } CMD_LINE_PARAM_t; template diff --git a/src/CAcquisition.cpp b/src/CAcquisition.cpp index a2bc74dc8446d7b4e21dbc9eefb8fb0630ec044a..81ff9c60ca6431175e3027ce0690e71ade3e0b1e 100644 --- a/src/CAcquisition.cpp +++ b/src/CAcquisition.cpp @@ -26,6 +26,8 @@ //#define TIME_SERVER_ENABLE //#define SINGLE_THREAD +using ntof::utils::Flock; + int CAcquisition::bufferPoolIndex_ = -1; CAcquisition::CAcquisition( @@ -102,6 +104,14 @@ CAcquisition::CAcquisition( CAcquisition::~CAcquisition() {} +void CAcquisition::setLockFile(const std::string &lockFile) +{ + if (lockFile.empty()) + lockFile_.reset(); + else + lockFile_.reset(new Flock(Flock::Shared, lockFile)); +} + ACQUISITION_STATE_t CAcquisition::GetState() { return static_cast(state_.getValue()); @@ -260,6 +270,11 @@ void CAcquisition::Acquisition() state_.clearWarnings(); state_.setValue(static_cast(ACQUISITION_STATE_t::THREAD_INIT)); + std::shared_ptr lockFile(lockFile_); + std::unique_lock fileLocker; + if (lockFile) + fileLocker = std::unique_lock(*lockFile); + while (static_cast(writerState_->getValue()) != WRITER_STATE_t::ERROR && (stop_ != true)) diff --git a/src/CDaq.cpp b/src/CDaq.cpp index bcbbdff1a57e7164861c9e9aa8b6ced7e28b6ea8..ee0b0e8f718bb23fd6ad99124b1027292319168b 100644 --- a/src/CDaq.cpp +++ b/src/CDaq.cpp @@ -114,7 +114,7 @@ void CDaq::InitServiceDim() LOG_TRACE << "Exiting CDaq::InitServiceDim"; } -void CDaq::InitializeThreads() +void CDaq::InitializeThreads(const std::string &lockFile) { LOG_TRACE << "Entering CDaq::InitializeThreads"; @@ -122,9 +122,12 @@ void CDaq::InitializeThreads() { writer_ = std::make_shared(hwConfigFilename_, hostName_, acqQueue_, cards_, &state_, cmdLineParams_); + writer_->setLockFile(lockFile); + acq_ = std::make_shared( hostName_, acqQueue_, cards_, writer_->GetState(), cmdLineParams_.timingEventName, cmdLineParams_); + acq_->setLockFile(lockFile); } catch (const std::bad_alloc &ex) { diff --git a/src/CWriter.cpp b/src/CWriter.cpp index e341261228c219a611db3b6bff0f560d990febd5..e328a930cf44d5fd7218e5a3c13505e30fa6405f 100644 --- a/src/CWriter.cpp +++ b/src/CWriter.cpp @@ -29,6 +29,7 @@ using namespace boost::interprocess; using namespace ntof; +using ntof::utils::Flock; CWriter::CWriter(std::string hwConfigFilename, std::string hostName, @@ -95,6 +96,14 @@ CWriter::CWriter(std::string hwConfigFilename, zsMode_ = ZeroSuppression::zsMode::INDEPENDENT; } +void CWriter::setLockFile(const std::string &lockFile) +{ + if (lockFile.empty()) + lockFile_.reset(); + else + lockFile_.reset(new Flock(Flock::Shared, lockFile)); +} + ntof::dim::DIMState *CWriter::GetState() { return &state_; @@ -347,6 +356,11 @@ void CWriter::Writer() state_.clearWarnings(); state_.setValue(static_cast(WRITER_STATE_t::INIT)); + std::shared_ptr lockFile(lockFile_); + std::unique_lock fileLocker; + if (lockFile) + fileLocker = std::unique_lock(*lockFile); + while (!stop_) { try diff --git a/src/DaqManager.cpp b/src/DaqManager.cpp index 08683198b3c93728345228c7346aba70c5c11278..133a20f2324a390fceef84a173ce7b1fcde90819 100644 --- a/src/DaqManager.cpp +++ b/src/DaqManager.cpp @@ -69,6 +69,7 @@ int main(int argc, char **argv) cmdLineParams.nbVirtualCards = 2; cmdLineParams.acqPoolSize = 20; cmdLineParams.spdLogTrace = false; + cmdLineParams.lockFile = "/run/lock/puppetlock"; // Catch ctrl+c signal struct sigaction action; @@ -263,7 +264,7 @@ int main(int argc, char **argv) try { daq.FindDevices(); - daq.InitializeThreads(); + daq.InitializeThreads(cmdLineParams.lockFile); } catch (const CDaqException &ex) { @@ -542,8 +543,13 @@ static int ProcessCmdLineParams(int argc, "log-path", boost::program_options::value(&cmd_line_params.logPath) ->default_value("/DAQ/log/DaqManager/"), - "set path for log file")("v", "set logger to debug level")( - "vv", "set logger to trace level")("no-cal", "disable card calibration")( + "set path for log file")( + "lock-file", + boost::program_options::value(&cmd_line_params.lockFile) + ->default_value("/run/lock/puppetlock"), + "set flock(2) file to lock during operation")( + "v", "set logger to debug level")("vv", "set logger to trace level")( + "no-cal", "disable card calibration")( "dim-dns", boost::program_options::value(&cmd_line_params.dimDnsServer) ->default_value("ntofproxy-1"),