00001 #ifndef ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH
00002 #define ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH
00003
00004 #include <boost/thread.hpp>
00005 #include "artdaq-core/Data/Fragment.hh"
00006 #include "fhiclcpp/fwd.h"
00007
00008 #include <mutex>
00009 #include <condition_variable>
00010
00011 namespace artdaq
00012 {
00013 class RequestReceiver
00014 {
00015 public:
00016 RequestReceiver();
00017 RequestReceiver(const fhicl::ParameterSet& ps);
00018 virtual ~RequestReceiver();
00019
00023 void setupRequestListener();
00024
00028 void stopRequestReceiverThread();
00029
00033 void startRequestReceiverThread();
00034
00038 void receiveRequestsLoop();
00039
00040 std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> GetRequests() const
00041 {
00042 std::unique_lock<std::mutex> lk(request_mutex_);
00043 std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
00044 for (auto& in : requests_) {
00045 out[in.first] = in.second;
00046 }
00047 return out;
00048 }
00049
00050 void RemoveRequest(artdaq::Fragment::sequence_id_t reqID);
00051
00052 bool isRunning() { return running_; }
00053
00054 void ClearRequests() {
00055 std::unique_lock<std::mutex> lk(request_mutex_);
00056 requests_.clear();
00057 }
00058
00059 size_t size() { return requests_.size(); }
00060
00061 bool WaitForRequests(int timeout_ms) {
00062 std::unique_lock<std::mutex> lk(request_mutex_);
00063 return request_cv_.wait_for(lk, std::chrono::milliseconds(timeout_ms), [this]() {return requests_.size() > 0; });
00064 }
00065 private:
00066
00067
00068 int request_port_;
00069 std::string request_addr_;
00070 bool running_;
00071
00072
00073 int request_socket_;
00074 std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> requests_;
00075 std::map<artdaq::Fragment::sequence_id_t, std::chrono::steady_clock::time_point> request_timing_;
00076 std::atomic<bool> request_stop_requested_;
00077 std::chrono::steady_clock::time_point request_stop_timeout_;
00078 std::atomic<bool> request_received_;
00079 size_t end_of_run_timeout_ms_;
00080 std::atomic<bool> should_stop_;
00081 mutable std::mutex request_mutex_;
00082 mutable std::mutex state_mutex_;
00083 std::condition_variable request_cv_;
00084 boost::thread requestThread_;
00085
00086 std::atomic<artdaq::Fragment::sequence_id_t> highest_seen_request_;
00087 };
00088 }
00089
00090
00091 #endif //ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH