/******************************************************************************** * Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ #ifndef FAIRMQSTATEQUEUE_H_ #define FAIRMQSTATEQUEUE_H_ #include #include #include #include #include // pair #include namespace fair::mq { class StateQueue { public: StateQueue() {} ~StateQueue() {} fair::mq::State WaitForNext() { std::unique_lock lock(fMtx); while (fStates.empty()) { fCV.wait_for(lock, std::chrono::milliseconds(50)); } fair::mq::State state = fStates.front(); if (state == fair::mq::State::Error) { throw DeviceErrorState("Controlled device transitioned to error state."); } fStates.pop(); return state; } template std::pair WaitForNext(std::chrono::duration const& duration) { std::unique_lock lock(fMtx); fCV.wait_for(lock, duration); if (fStates.empty()) { return { false, fair::mq::State::Ok }; } fair::mq::State state = fStates.front(); if (state == fair::mq::State::Error) { throw DeviceErrorState("Controlled device transitioned to error state."); } fStates.pop(); return { true, state }; } void WaitForState(fair::mq::State state) { while (WaitForNext() != state) {} } void Push(fair::mq::State state) { { std::lock_guard lock(fMtx); fStates.push(state); } fCV.notify_all(); } void Clear() { std::lock_guard lock(fMtx); fStates = std::queue(); } private: std::queue fStates; std::mutex fMtx; std::condition_variable fCV; }; } // namespace fair::mq #endif /* FAIRMQSTATEQUEUE_H_ */