Newer
Older
Martin Christoph Hierholzer
committed
/*
* ThreadedFanOut.h
*
* Created on: Jun 15, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_THREADED_FAN_OUT_H
#define CHIMERATK_THREADED_FAN_OUT_H
#include <ChimeraTK/NDRegisterAccessor.h>
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
#include "Application.h"
Martin Christoph Hierholzer
committed
#include "FanOut.h"
#include "InternalModule.h"
namespace ChimeraTK {
/** FanOut implementation with an internal thread which waits for new data which is read from the given feeding
* implementation and distributed to any number of slaves. */
Martin Christoph Hierholzer
committed
template<typename UserType>
class ThreadedFanOut : public FanOut<UserType>, public InternalModule {
public:
ThreadedFanOut(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> feedingImpl)
Martin Christoph Hierholzer
committed
: FanOut<UserType>(feedingImpl)
{}
Martin Christoph Hierholzer
committed
~ThreadedFanOut() {
deactivate();
Martin Christoph Hierholzer
committed
}
void activate() override {
assert(!_thread.joinable());
_thread = boost::thread([this] { this->run(); });
}
void deactivate() override {
if(_thread.joinable()) {
_thread.interrupt();
Martin Christoph Hierholzer
committed
FanOut<UserType>::impl->interrupt();
Martin Christoph Hierholzer
committed
_thread.join();
}
assert(!_thread.joinable());
}
/** Synchronise feeder and the consumers. This function is executed in the separate thread. */
void run() {
Martin Christoph Hierholzer
committed
Application::registerThread("ThFO"+FanOut<UserType>::impl->getName());
Application::testableModeLock("start");
Martin Christoph Hierholzer
committed
while(true) {
// receive data
Martin Christoph Hierholzer
committed
boost::this_thread::interruption_point();
Profiler::stopMeasurement();
FanOut<UserType>::impl->read();
Profiler::startMeasurement();
boost::this_thread::interruption_point();
// send out copies to slaves
for(auto &slave : FanOut<UserType>::slaves) {
Martin Christoph Hierholzer
committed
// do not send copy if no data is expected (e.g. trigger)
if(slave->getNumberOfSamples() != 0) {
slave->accessChannel(0) = FanOut<UserType>::impl->accessChannel(0);
}
Martin Christoph Hierholzer
committed
bool dataLoss = slave->write();
if(dataLoss) Application::incrementDataLossCounter();
Martin Christoph Hierholzer
committed
}
}
}