diff --git a/fairmq/CMakeLists.txt b/fairmq/CMakeLists.txt index 04b7d8ed..6f602994 100644 --- a/fairmq/CMakeLists.txt +++ b/fairmq/CMakeLists.txt @@ -6,7 +6,7 @@ # copied verbatim in the file "LICENSE" # ################################################################################ -configure_file(${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/bsampler-sink.json ${CMAKE_BINARY_DIR}/bin/config/example-bsampler-sink.json) +configure_file(${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/bsampler-sink.json ${CMAKE_BINARY_DIR}/bin/config/bsampler-sink.json) configure_file(${CMAKE_SOURCE_DIR}/fairmq/examples/1-sampler-sink/sampler-sink.json ${CMAKE_BINARY_DIR}/bin/config/ex1-sampler-sink.json) configure_file(${CMAKE_SOURCE_DIR}/fairmq/examples/2-sampler-processor-sink/sampler-processor-sink.json ${CMAKE_BINARY_DIR}/bin/config/ex2-sampler-processor-sink.json) @@ -18,6 +18,7 @@ Set(INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/fairmq/examples/1-sampler-sink ${CMAKE_SOURCE_DIR}/fairmq/examples/2-sampler-processor-sink ${CMAKE_SOURCE_DIR}/fairmq/examples/req-rep + ${CMAKE_CURRENT_BINARY_DIR} ) Set(SYSTEM_INCLUDE_DIRECTORIES @@ -27,8 +28,8 @@ Set(SYSTEM_INCLUDE_DIRECTORIES If(PROTOBUF_FOUND) Set(INCLUDE_DIRECTORIES ${INCLUDE_DIRECTORIES} - # # following directory is only for protobuf tests and is not essential part of FairMQ - #${CMAKE_SOURCE_DIR}/fairmq/prototest + # following directory is only for protobuf tests and is not essential part of FairMQ + # ${CMAKE_SOURCE_DIR}/fairmq/prototest ) Set(SYSTEM_INCLUDE_DIRECTORIES ${SYSTEM_INCLUDE_DIRECTORIES} @@ -100,9 +101,18 @@ set(SRCS if(PROTOBUF_FOUND) # following source files are only for protobuf tests and are not essential part of FairMQ + # add_custom_command( + # OUTPUT + # ${CMAKE_CURRENT_BINARY_DIR}/payload.pb.h + # ${CMAKE_CURRENT_BINARY_DIR}/payload.pb.cc + # COMMAND + # ${SIMPATH}/bin/protoc -I=. --cpp_out=${CMAKE_CURRENT_BINARY_DIR} payload.proto + # WORKING_DIRECTORY + # ${CMAKE_SOURCE_DIR}/fairmq/prototest + # ) # set(SRCS # ${SRCS} - # "prototest/payload.pb.cc" + # ${CMAKE_CURRENT_BINARY_DIR}/payload.pb.cc # "prototest/FairMQProtoSampler.cxx" # "prototest/FairMQBinSampler.cxx" # "prototest/FairMQBinSink.cxx" @@ -209,10 +219,10 @@ set(Exe_Source # if(PROTOBUF_FOUND) # set(Exe_Source # ${Exe_Source} -# run/runBinSampler.cxx -# run/runProtoSampler.cxx -# run/runBinSink.cxx -# run/runProtoSink.cxx +# prototest/runBinSampler.cxx +# prototest/runProtoSampler.cxx +# prototest/runBinSink.cxx +# prototest/runProtoSink.cxx # ) # endif(PROTOBUF_FOUND) diff --git a/fairmq/FairMQChannel.cxx b/fairmq/FairMQChannel.cxx index 29d82f31..ede4b98b 100644 --- a/fairmq/FairMQChannel.cxx +++ b/fairmq/FairMQChannel.cxx @@ -30,9 +30,12 @@ FairMQChannel::FairMQChannel() , fSndBufSize(1000) , fRcvBufSize(1000) , fRateLogging(1) - , fSocket() + , fSocket(nullptr) , fChannelName("") , fIsValid(false) + , fPoller(nullptr) + , fCmdSocket(nullptr) + , fTransportFactory(nullptr) { } @@ -43,13 +46,16 @@ FairMQChannel::FairMQChannel(const string& type, const string& method, const str , fSndBufSize(1000) , fRcvBufSize(1000) , fRateLogging(1) - , fSocket() + , fSocket(nullptr) , fChannelName("") , fIsValid(false) + , fPoller(nullptr) + , fCmdSocket(nullptr) + , fTransportFactory(nullptr) { } -std::string FairMQChannel::GetType() +std::string FairMQChannel::GetType() const { try { @@ -58,11 +64,11 @@ std::string FairMQChannel::GetType() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetType: " << boost::diagnostic_information(e); } } -std::string FairMQChannel::GetMethod() +std::string FairMQChannel::GetMethod() const { try { @@ -71,11 +77,11 @@ std::string FairMQChannel::GetMethod() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetMethod: " << boost::diagnostic_information(e); } } -std::string FairMQChannel::GetAddress() +std::string FairMQChannel::GetAddress() const { try { @@ -84,11 +90,11 @@ std::string FairMQChannel::GetAddress() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetAddress: " << boost::diagnostic_information(e); } } -int FairMQChannel::GetSndBufSize() +int FairMQChannel::GetSndBufSize() const { try { @@ -97,11 +103,11 @@ int FairMQChannel::GetSndBufSize() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetSndBufSize: " << boost::diagnostic_information(e); } } -int FairMQChannel::GetRcvBufSize() +int FairMQChannel::GetRcvBufSize() const { try { @@ -110,11 +116,11 @@ int FairMQChannel::GetRcvBufSize() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetRcvBufSize: " << boost::diagnostic_information(e); } } -int FairMQChannel::GetRateLogging() +int FairMQChannel::GetRateLogging() const { try { @@ -123,7 +129,7 @@ int FairMQChannel::GetRateLogging() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::GetRateLogging: " << boost::diagnostic_information(e); } } @@ -132,75 +138,86 @@ void FairMQChannel::UpdateType(const std::string& type) try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fType = type; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateType: " << boost::diagnostic_information(e); } } + void FairMQChannel::UpdateMethod(const std::string& method) { try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fMethod = method; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateMethod: " << boost::diagnostic_information(e); } } + void FairMQChannel::UpdateAddress(const std::string& address) { try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fAddress = address; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateAddress: " << boost::diagnostic_information(e); } } + void FairMQChannel::UpdateSndBufSize(const int sndBufSize) { try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fSndBufSize = sndBufSize; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateSndBufSize: " << boost::diagnostic_information(e); } } + void FairMQChannel::UpdateRcvBufSize(const int rcvBufSize) { try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fRcvBufSize = rcvBufSize; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateRcvBufSize: " << boost::diagnostic_information(e); } } + void FairMQChannel::UpdateRateLogging(const int rateLogging) { try { boost::unique_lock scoped_lock(channelMutex); + fIsValid = false; fRateLogging = rateLogging; } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::UpdateRateLogging: " << boost::diagnostic_information(e); } } -bool FairMQChannel::IsValid() +bool FairMQChannel::IsValid() const { try { @@ -209,7 +226,7 @@ bool FairMQChannel::IsValid() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::IsValid: " << boost::diagnostic_information(e); } } @@ -220,7 +237,7 @@ bool FairMQChannel::ValidateChannel() boost::unique_lock scoped_lock(channelMutex); stringstream ss; - ss << "Validating channel " << fChannelName << "... "; + ss << "Validating channel \"" << fChannelName << "\"... "; if (fIsValid) { @@ -229,47 +246,88 @@ bool FairMQChannel::ValidateChannel() return true; } + // validate socket type const string socketTypeNames[] = { "sub", "pub", "pull", "push", "req", "rep", "xsub", "xpub", "dealer", "router", "pair" }; const set socketTypes(socketTypeNames, socketTypeNames + sizeof(socketTypeNames) / sizeof(string)); if (socketTypes.find(fType) == socketTypes.end()) { ss << "INVALID"; LOG(DEBUG) << ss.str(); - LOG(DEBUG) << "Invalid channel type: " << fType; + LOG(DEBUG) << "Invalid channel type: \"" << fType << "\""; return false; } + // validate socket method const string socketMethodNames[] = { "bind", "connect" }; const set socketMethods(socketMethodNames, socketMethodNames + sizeof(socketMethodNames) / sizeof(string)); if (socketMethods.find(fMethod) == socketMethods.end()) { ss << "INVALID"; LOG(DEBUG) << ss.str(); - LOG(DEBUG) << "Invalid channel method: " << fMethod; + LOG(DEBUG) << "Invalid channel method: \"" << fMethod << "\""; return false; } + // validate socket address if (fAddress == "unspecified" || fAddress == "") { ss << "INVALID"; LOG(DEBUG) << ss.str(); - LOG(DEBUG) << "invalid channel address: " << fAddress; + LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\""; return false; } + else + { + // check if address is a tcp or ipc address + if (fAddress.compare(0, 6, "tcp://") == 0) + { + // check if TCP address contains port delimiter + string addressString = fAddress.substr(6); + if (addressString.find(":") == string::npos) + { + ss << "INVALID"; + LOG(DEBUG) << ss.str(); + LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (missing port?)"; + return false; + } + } + else if (fAddress.compare(0, 6, "ipc://") == 0) + { + // check if IPC address is not empty + string addressString = fAddress.substr(6); + if (addressString == "") + { + ss << "INVALID"; + LOG(DEBUG) << ss.str(); + LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (empty IPC address?)"; + return false; + } + } + else + { + // if neither TCP or IPC is specified, return invalid + ss << "INVALID"; + LOG(DEBUG) << ss.str(); + LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (missing protocol specifier?)"; + return false; + } + } + // validate socket buffer size for sending if (fSndBufSize < 0) { ss << "INVALID"; LOG(DEBUG) << ss.str(); - LOG(DEBUG) << "invalid channel send buffer size: " << fSndBufSize; + LOG(DEBUG) << "invalid channel send buffer size: \"" << fSndBufSize << "\""; return false; } + // validate socket buffer size for receiving if (fRcvBufSize < 0) { ss << "INVALID"; LOG(DEBUG) << ss.str(); - LOG(DEBUG) << "invalid channel receive buffer size: " << fRcvBufSize; + LOG(DEBUG) << "invalid channel receive buffer size: \"" << fRcvBufSize << "\""; return false; } @@ -280,35 +338,160 @@ bool FairMQChannel::ValidateChannel() } catch (boost::exception& e) { - LOG(ERROR) << boost::diagnostic_information(e); + LOG(ERROR) << "Exception caught in FairMQChannel::ValidateChannel: " << boost::diagnostic_information(e); } } +bool FairMQChannel::InitCommandInterface(FairMQTransportFactory* factory) +{ + fTransportFactory = factory; + + fCmdSocket = fTransportFactory->CreateSocket("sub", "device-commands", 1); + fCmdSocket->Connect("inproc://commands"); + + fPoller = fTransportFactory->CreatePoller(*fSocket, *fCmdSocket); + return true; +} + void FairMQChannel::ResetChannel() { - // TODO: implement resetting + fIsValid = false; + // TODO: implement channel resetting } -int FairMQChannel::Send(FairMQMessage* msg, const string& flag) +int FairMQChannel::Send(FairMQMessage* msg, const string& flag) const { - return fSocket->Send(msg, flag); + if (flag == "") + { + fPoller->Poll(-1); + + if (fPoller->CheckInput(0)) + { + HandleCommand(); + return -1; + } + + if (fPoller->CheckOutput(1)) + { + return fSocket->Send(msg, flag); + } + } + else + { + return fSocket->Send(msg, flag); + } + + return -1; } -int FairMQChannel::Send(FairMQMessage* msg, const int flags) +int FairMQChannel::Send(FairMQMessage* msg, const int flags) const { - return fSocket->Send(msg, flags); + if (flags == 0) + { + fPoller->Poll(-1); + + if (fPoller->CheckInput(0)) + { + HandleCommand(); + return -1; + } + + if (fPoller->CheckOutput(1)) + { + return fSocket->Send(msg, flags); + } + } + else + { + return fSocket->Send(msg, flags); + } + + return -1; } -int FairMQChannel::Receive(FairMQMessage* msg, const string& flag) +int FairMQChannel::Receive(FairMQMessage* msg, const string& flag) const { - return fSocket->Receive(msg, flag); + if (flag == "") + { + fPoller->Poll(-1); + + if (fPoller->CheckInput(0)) + { + HandleCommand(); + return -1; + } + + if (fPoller->CheckInput(1)) + { + return fSocket->Receive(msg, flag); + } + } + else + { + return fSocket->Receive(msg, flag); + } + + return -1; } -int FairMQChannel::Receive(FairMQMessage* msg, const int flags) +int FairMQChannel::Receive(FairMQMessage* msg, const int flags) const { - return fSocket->Receive(msg, flags); + if (flags == 0) + { + fPoller->Poll(-1); + + if (fPoller->CheckInput(0)) + { + HandleCommand(); + return -1; + } + + if (fPoller->CheckInput(1)) + { + return fSocket->Receive(msg, flags); + } + } + else + { + return fSocket->Receive(msg, flags); + } + + return -1; +} + +bool FairMQChannel::ExpectsAnotherPart() const +{ + int64_t more = 0; + size_t more_size = sizeof more; + + if (fSocket) + { + fSocket->GetOption("rcv-more", &more, &more_size); + if (more) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} + +inline bool FairMQChannel::HandleCommand() const +{ + FairMQMessage* cmd = fTransportFactory->CreateMessage(); + fCmdSocket->Receive(cmd, 0); + delete cmd; + return true; } FairMQChannel::~FairMQChannel() { + delete fCmdSocket; + delete fPoller; } diff --git a/fairmq/FairMQChannel.h b/fairmq/FairMQChannel.h index fe12c1e5..b9a7f21c 100644 --- a/fairmq/FairMQChannel.h +++ b/fairmq/FairMQChannel.h @@ -19,7 +19,12 @@ #include +#include "FairMQTransportFactory.h" #include "FairMQSocket.h" +#include "FairMQPoller.h" + +class FairMQPoller; +class FairMQTransportFactory; class FairMQChannel { @@ -30,12 +35,12 @@ class FairMQChannel FairMQChannel(const std::string& type, const std::string& method, const std::string& address); virtual ~FairMQChannel(); - std::string GetType(); - std::string GetMethod(); - std::string GetAddress(); - int GetSndBufSize(); - int GetRcvBufSize(); - int GetRateLogging(); + std::string GetType() const; + std::string GetMethod() const; + std::string GetAddress() const; + int GetSndBufSize() const; + int GetRcvBufSize() const; + int GetRateLogging() const; void UpdateType(const std::string& type); void UpdateMethod(const std::string& method); @@ -44,19 +49,24 @@ class FairMQChannel void UpdateRcvBufSize(const int rcvBufSize); void UpdateRateLogging(const int rateLogging); - bool IsValid(); + bool IsValid() const; bool ValidateChannel(); + bool InitCommandInterface(FairMQTransportFactory* factory); void ResetChannel(); FairMQSocket* fSocket; // Wrappers for the socket methods to simplify the usage of channels - int Send(FairMQMessage* msg, const std::string& flag = ""); - int Send(FairMQMessage* msg, const int flags); - int Receive(FairMQMessage* msg, const std::string& flag = ""); - int Receive(FairMQMessage* msg, const int flags); + int Send(FairMQMessage* msg, const std::string& flag = "") const; + int Send(FairMQMessage* msg, const int flags) const; + int Receive(FairMQMessage* msg, const std::string& flag = "") const; + int Receive(FairMQMessage* msg, const int flags) const; + + /// Checks if the socket is expecting to receive another part of a multipart message. + /// \return Return true if the socket expects another part of a multipart message and false otherwise. + bool ExpectsAnotherPart() const; private: std::string fType; @@ -69,6 +79,13 @@ class FairMQChannel std::string fChannelName; bool fIsValid; + FairMQPoller* fPoller; + FairMQSocket* fCmdSocket; + + FairMQTransportFactory* fTransportFactory; + + bool HandleCommand() const; + // use static mutex to make the class easily copyable // implication: same mutex is used for all instances of the class // this does not hurt much, because mutex is used only during initialization with very low contention diff --git a/fairmq/FairMQDevice.cxx b/fairmq/FairMQDevice.cxx index efb5ec86..d3cb266b 100644 --- a/fairmq/FairMQDevice.cxx +++ b/fairmq/FairMQDevice.cxx @@ -14,6 +14,9 @@ #include #include // for std::sort() +#include // for catching system signals + +#include // for the InteractiveStateLoop #include #include // for choosing random port in range @@ -25,6 +28,13 @@ using namespace std; +// boost::function and a wrapper to catch the signals +boost::function sigHandler; +static void CallSignalHandler(int signal) +{ + sigHandler(signal); +} + FairMQDevice::FairMQDevice() : fChannels() , fId() @@ -33,26 +43,60 @@ FairMQDevice::FairMQDevice() , fPortRangeMin(22000) , fPortRangeMax(32000) , fLogIntervalInMs(1000) - , fCommandSocket() - , fTransportFactory(NULL) + , fCmdSocket(nullptr) + , fTransportFactory(nullptr) , fInitialValidationFinished(false) , fInitialValidationCondition() , fInitialValidationMutex() + , fCatchingSignals(false) { } +void FairMQDevice::CatchSignals() +{ + if (!fCatchingSignals) + { + // setup signal catching + sigHandler = std::bind1st(std::mem_fun(&FairMQDevice::SignalHandler), this); + struct sigaction action; + action.sa_handler = CallSignalHandler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); + + fCatchingSignals = true; + } +} + +void FairMQDevice::SignalHandler(int signal) +{ + LOG(INFO) << "Caught signal " << signal; + + ChangeState(STOP); + + ChangeState(RESET_TASK); + WaitForEndOfState(RESET_TASK); + + ChangeState(RESET_DEVICE); + WaitForEndOfState(RESET_DEVICE); + + ChangeState(END); +} + void FairMQDevice::InitWrapper() { - LOG(INFO) << "DEVICE: Initializing..."; - - fCommandSocket = fTransportFactory->CreateSocket("pair", "device-commands", 1); - fCommandSocket->Bind("inproc://commands"); + if (!fCmdSocket) + { + fCmdSocket = fTransportFactory->CreateSocket("pub", "device-commands", 1); + fCmdSocket->Bind("inproc://commands"); + } // List to store the uninitialized channels. list uninitializedChannels; - for (map< string,vector >::iterator mi = fChannels.begin(); mi != fChannels.end(); ++mi) + for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) { - for (vector::iterator vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) + for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) { // set channel name: name + vector index stringstream ss; @@ -66,8 +110,9 @@ void FairMQDevice::InitWrapper() // go over the list of channels until all are initialized (and removed from the uninitialized list) int numAttempts = 0; int maxAttempts = fMaxInitializationTime; - do { - list::iterator itr = uninitializedChannels.begin(); + do + { + auto itr = uninitializedChannels.begin(); while (itr != uninitializedChannels.end()) { @@ -75,6 +120,7 @@ void FairMQDevice::InitWrapper() { if (InitChannel(*(*itr))) { + (*itr)->InitCommandInterface(fTransportFactory); uninitializedChannels.erase(itr++); } else @@ -89,7 +135,7 @@ void FairMQDevice::InitWrapper() } } - // notify parent thread about end of processing. + // notify parent thread about completion of first validation. boost::lock_guard lock(fInitialValidationMutex); fInitialValidationFinished = true; fInitialValidationCondition.notify_one(); @@ -106,7 +152,6 @@ void FairMQDevice::InitWrapper() { boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } - } while (!uninitializedChannels.empty()); Init(); @@ -134,7 +179,7 @@ void FairMQDevice::Init() bool FairMQDevice::InitChannel(FairMQChannel& ch) { - LOG(DEBUG) << "Initializing channel " << ch.fChannelName << " to <" << ch.fType << "> data"; + LOG(DEBUG) << "Initializing channel " << ch.fChannelName << " (" << ch.fType << ")"; // initialize the socket ch.fSocket = fTransportFactory->CreateSocket(ch.fType, ch.fChannelName, 1); // set high water marks @@ -211,15 +256,15 @@ void FairMQDevice::SortChannel(const string& name, const bool reindex) { if (fChannels.find(name) != fChannels.end()) { - sort(fChannels[name].begin(), fChannels[name].end(), SortSocketsByAddress); + sort(fChannels.at(name).begin(), fChannels.at(name).end(), SortSocketsByAddress); if (reindex) { - for (vector::iterator vi = fChannels[name].begin(); vi != fChannels[name].end(); ++vi) + for (auto vi = fChannels.at(name).begin(); vi != fChannels.at(name).end(); ++vi) { // set channel name: name + vector index stringstream ss; - ss << name << "[" << vi - fChannels[name].begin() << "]"; + ss << name << "[" << vi - fChannels.at(name).begin() << "]"; vi->fChannelName = ss.str(); } } @@ -234,7 +279,7 @@ void FairMQDevice::PrintChannel(const string& name) { if (fChannels.find(name) != fChannels.end()) { - for (vector::iterator vi = fChannels[name].begin(); vi != fChannels[name].end(); ++vi) + for (auto vi = fChannels[name].begin(); vi != fChannels[name].end(); ++vi) { LOG(INFO) << vi->fChannelName << ": " << vi->fType << " | " @@ -269,6 +314,11 @@ void FairMQDevice::RunWrapper() LOG(ERROR) << e.what(); } + if (CheckCurrentState(RUNNING)) + { + ChangeState(internal_READY); + } + // notify parent thread about end of processing. boost::lock_guard lock(fStateMutex); fStateFinished = true; @@ -281,7 +331,7 @@ void FairMQDevice::Run() void FairMQDevice::Pause() { - while (GetCurrentState() == PAUSED) + while (CheckCurrentState(PAUSED)) { try { @@ -296,38 +346,6 @@ void FairMQDevice::Pause() } } -void FairMQDevice::ResetTaskWrapper() -{ - ResetTask(); - - ChangeState(internal_DEVICE_READY); - - // notify parent thread about end of processing. - boost::lock_guard lock(fStateMutex); - fStateFinished = true; - fStateCondition.notify_one(); -} - -void FairMQDevice::ResetTask() -{ -} - -void FairMQDevice::ResetWrapper() -{ - Reset(); - - ChangeState(internal_IDLE); - - // notify parent thread about end of processing. - boost::lock_guard lock(fStateMutex); - fStateFinished = true; - fStateCondition.notify_one(); -} - -void FairMQDevice::Reset() -{ -} - // Method for setting properties represented as a string. void FairMQDevice::SetProperty(const int key, const string& value) { @@ -417,10 +435,10 @@ void FairMQDevice::LogSocketRates() vector filteredChannelNames; // iterate over the channels map - for (map< string,vector >::iterator mi = fChannels.begin(); mi != fChannels.end(); ++mi) + for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) { // iterate over the channels vector - for (vector::iterator vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) + for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) { if (vi->fRateLogging == 1) { @@ -449,7 +467,7 @@ void FairMQDevice::LogSocketRates() vector msgPerSecOut(numFilteredSockets); int i = 0; - for (vector::iterator itr = filteredSockets.begin(); itr != filteredSockets.end(); ++itr) + for (auto itr = filteredSockets.begin(); itr != filteredSockets.end(); ++itr) { bytesIn.at(i) = (*itr)->GetBytesRx(); bytesOut.at(i) = (*itr)->GetBytesTx(); @@ -460,7 +478,7 @@ void FairMQDevice::LogSocketRates() t0 = get_timestamp(); - while (GetCurrentState() == RUNNING) + while (CheckCurrentState(RUNNING)) { try { @@ -470,7 +488,7 @@ void FairMQDevice::LogSocketRates() i = 0; - for (vector::iterator itr = filteredSockets.begin(); itr != filteredSockets.end(); itr++) + for (auto itr = filteredSockets.begin(); itr != filteredSockets.end(); itr++) { bytesInNew.at(i) = (*itr)->GetBytesRx(); mbPerSecIn.at(i) = ((double)(bytesInNew.at(i) - bytesIn.at(i)) / (1024. * 1024.)) / (double)msSinceLastLog * 1000.; @@ -508,11 +526,148 @@ void FairMQDevice::LogSocketRates() // LOG(DEBUG) << "FairMQDevice::LogSocketRates() stopping"; } +void FairMQDevice::InteractiveStateLoop() +{ + char c; // hold the user console input + bool running = true; + + struct termios t; + tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure + t.c_lflag &= ~ICANON; // disable canonical input + tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings + + PrintInteractiveStateLoopHelp(); + + while (running && cin >> c) + { + switch (c) + { + case 'i': + LOG(INFO) << "[i] init device"; + ChangeState("INIT_DEVICE"); + break; + case 'j': + LOG(INFO) << "[j] init task"; + ChangeState("INIT_TASK"); + break; + case 'p': + LOG(INFO) << "[p] pause"; + ChangeState("PAUSE"); + break; + case 'r': + LOG(INFO) << "[r] run"; + ChangeState("RUN"); + break; + case 's': + LOG(INFO) << "[s] stop"; + ChangeState("STOP"); + break; + case 't': + LOG(INFO) << "[t] reset task"; + ChangeState("RESET_TASK"); + break; + case 'd': + LOG(INFO) << "[d] reset device"; + ChangeState("RESET_DEVICE"); + break; + case 'h': + LOG(INFO) << "[h] help"; + PrintInteractiveStateLoopHelp(); + break; + case 'q': + LOG(INFO) << "[q] end"; + ChangeState("END"); + if (CheckCurrentState("EXITING")) + { + running = false; + } + break; + default: + LOG(INFO) << "Invalid input: [" << c << "]"; + PrintInteractiveStateLoopHelp(); + break; + } + } + + tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure + t.c_lflag |= ICANON; // re-enable canonical input + tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings +} + +inline void FairMQDevice::PrintInteractiveStateLoopHelp() +{ + LOG(INFO) << "Use keys to control the state machine:"; + LOG(INFO) << "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device"; +} + void FairMQDevice::SendCommand(const string& command) { FairMQMessage* cmd = fTransportFactory->CreateMessage(command.size()); memcpy(cmd->GetData(), command.c_str(), command.size()); - fCommandSocket->Send(cmd, 0); + fCmdSocket->Send(cmd, 0); +} + +void FairMQDevice::ResetTaskWrapper() +{ + ResetTask(); + + ChangeState(internal_DEVICE_READY); + + // notify parent thread about end of processing. + boost::lock_guard lock(fStateMutex); + fStateFinished = true; + fStateCondition.notify_one(); +} + +void FairMQDevice::ResetTask() +{ +} + +void FairMQDevice::ResetWrapper() +{ + Reset(); + + ChangeState(internal_IDLE); + + // notify parent thread about end of processing. + boost::lock_guard lock(fStateMutex); + fStateFinished = true; + fStateCondition.notify_one(); +} + +void FairMQDevice::Reset() +{ + LOG(DEBUG) << "Resetting Device..."; + + // iterate over the channels map + for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) + { + // iterate over the channels vector + for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) + { + vi->fSocket->Close(); + delete vi->fSocket; + vi->fSocket = nullptr; + + delete vi->fPoller; + vi->fPoller = nullptr; + + vi->fCmdSocket->Close(); + delete vi->fCmdSocket; + vi->fCmdSocket = nullptr; + } + } + + LOG(DEBUG) << "Device reset finished!"; +} + +void FairMQDevice::Terminate() +{ + // Termination signal has to be sent only once to any socket. + if (fCmdSocket) + { + fCmdSocket->Terminate(); + } } void FairMQDevice::Shutdown() @@ -520,37 +675,54 @@ void FairMQDevice::Shutdown() LOG(DEBUG) << "Closing sockets..."; // iterate over the channels map - for (map< string,vector >::iterator mi = fChannels.begin(); mi != fChannels.end(); ++mi) + for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) { // iterate over the channels vector - for (vector::iterator vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) + for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) { - vi->fSocket->Close(); + if (vi->fSocket) + { + vi->fSocket->Close(); + } + if (vi->fCmdSocket) + { + vi->fCmdSocket->Close(); + } } } - fCommandSocket->Close(); + if (fCmdSocket) + { + fCmdSocket->Close(); + } LOG(DEBUG) << "Closed all sockets!"; } -void FairMQDevice::Terminate() -{ - // Termination signal has to be sent only once to any socket. - fCommandSocket->Terminate(); -} - FairMQDevice::~FairMQDevice() { // iterate over the channels map - for (map< string,vector >::iterator mi = fChannels.begin(); mi != fChannels.end(); ++mi) + for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) { // iterate over the channels vector - for (vector::iterator vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) + for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) { - delete vi->fSocket; + if (vi->fSocket) + { + delete vi->fSocket; + vi->fSocket = nullptr; + } + if (vi->fPoller) + { + delete vi->fPoller; + vi->fPoller = nullptr; + } } } - delete fCommandSocket; + if (fCmdSocket) + { + delete fCmdSocket; + fCmdSocket = nullptr; + } } diff --git a/fairmq/FairMQDevice.h b/fairmq/FairMQDevice.h index 3a2e1ecd..31cccfeb 100644 --- a/fairmq/FairMQDevice.h +++ b/fairmq/FairMQDevice.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include "FairMQConfigurable.h" #include "FairMQStateMachine.h" @@ -42,6 +42,8 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable FairMQDevice(); + void CatchSignals(); + virtual void LogSocketRates(); void SortChannel(const std::string& name, const bool reindex = true); @@ -49,6 +51,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable void WaitForInitialValidation(); + void InteractiveStateLoop(); + void PrintInteractiveStateLoopHelp(); + virtual void SetProperty(const int key, const std::string& value); virtual std::string GetProperty(const int key, const std::string& default_ = ""); virtual void SetProperty(const int key, const int value); @@ -60,7 +65,7 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable virtual ~FairMQDevice(); - std::map< std::string,std::vector > fChannels; + std::unordered_map< std::string,std::vector > fChannels; protected: std::string fId; @@ -74,7 +79,7 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable int fLogIntervalInMs; - FairMQSocket* fCommandSocket; + FairMQSocket* fCmdSocket; FairMQTransportFactory* fTransportFactory; @@ -95,7 +100,7 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable void ResetWrapper(); virtual void Reset(); - virtual void Shutdown(); + void Shutdown(); void Terminate(); void SendCommand(const std::string& command); @@ -108,6 +113,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable boost::condition_variable fInitialValidationCondition; boost::mutex fInitialValidationMutex; + void SignalHandler(int signal); + bool fCatchingSignals; + /// Copy Constructor FairMQDevice(const FairMQDevice&); FairMQDevice operator=(const FairMQDevice&); diff --git a/fairmq/FairMQPoller.h b/fairmq/FairMQPoller.h index fa833db3..b3cb21fe 100644 --- a/fairmq/FairMQPoller.h +++ b/fairmq/FairMQPoller.h @@ -15,12 +15,16 @@ #ifndef FAIRMQPOLLER_H_ #define FAIRMQPOLLER_H_ +#include + class FairMQPoller { public: - virtual void Poll(int timeout) = 0; - virtual bool CheckInput(int index) = 0; - virtual bool CheckOutput(int index) = 0; + virtual void Poll(const int timeout) = 0; + virtual bool CheckInput(const int index) = 0; + virtual bool CheckOutput(const int index) = 0; + virtual bool CheckInput(const std::string channelKey, const int index) = 0; + virtual bool CheckOutput(const std::string channelKey, const int index) = 0; virtual ~FairMQPoller() {}; }; diff --git a/fairmq/FairMQStateMachine.cxx b/fairmq/FairMQStateMachine.cxx index 906301c2..972e5a07 100644 --- a/fairmq/FairMQStateMachine.cxx +++ b/fairmq/FairMQStateMachine.cxx @@ -40,13 +40,12 @@ int FairMQStateMachine::GetEventNumber(std::string event) if (event == "INIT_TASK") return INIT_TASK; if (event == "RUN") return RUN; if (event == "PAUSE") return PAUSE; - if (event == "RESUME") return RESUME; if (event == "STOP") return STOP; if (event == "RESET_DEVICE") return RESET_DEVICE; if (event == "RESET_TASK") return RESET_TASK; if (event == "END") return END; LOG(ERROR) << "Requested number for non-existent event... " << event << std::endl - << "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, RESUME, STOP, RESET_DEVICE, RESET_TASK, END"; + << "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_DEVICE, RESET_TASK, END"; return -1; } @@ -74,9 +73,6 @@ bool FairMQStateMachine::ChangeState(int event) case PAUSE: process_event(FairMQFSM::PAUSE()); return true; - case RESUME: - process_event(FairMQFSM::RESUME()); - return true; case STOP: process_event(FairMQFSM::STOP()); return true; @@ -94,7 +90,7 @@ bool FairMQStateMachine::ChangeState(int event) return true; default: LOG(ERROR) << "Requested unsupported state: " << event << std::endl - << "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, RESUME, STOP, RESET_TASK, RESET_DEVICE, END"; + << "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END"; return false; } } diff --git a/fairmq/FairMQStateMachine.h b/fairmq/FairMQStateMachine.h index 5f1626cd..56c83525 100644 --- a/fairmq/FairMQStateMachine.h +++ b/fairmq/FairMQStateMachine.h @@ -39,22 +39,22 @@ namespace FairMQFSM { // defining events for the boost MSM state machine -struct INIT_DEVICE {}; -struct internal_DEVICE_READY {}; -struct INIT_TASK {}; -struct internal_READY {}; -struct RUN {}; -struct PAUSE {}; -struct RESUME {}; -struct STOP {}; -struct RESET_TASK {}; -struct RESET_DEVICE {}; -struct internal_IDLE {}; -struct END {}; +struct INIT_DEVICE { std::string name() const { return "INIT_DEVICE"; } }; +struct internal_DEVICE_READY { std::string name() const { return "internal_DEVICE_READY"; } }; +struct INIT_TASK { std::string name() const { return "INIT_TASK"; } }; +struct internal_READY { std::string name() const { return "internal_READY"; } }; +struct RUN { std::string name() const { return "RUN"; } }; +struct PAUSE { std::string name() const { return "PAUSE"; } }; +struct STOP { std::string name() const { return "STOP"; } }; +struct RESET_TASK { std::string name() const { return "RESET_TASK"; } }; +struct RESET_DEVICE { std::string name() const { return "RESET_DEVICE"; } }; +struct internal_IDLE { std::string name() const { return "internal_IDLE"; } }; +struct END { std::string name() const { return "END"; } }; // defining the boost MSM state machine struct FairMQFSM_ : public msm::front::state_machine_def { + public: FairMQFSM_() : fState() , fStateThread() @@ -102,6 +102,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = IDLE; + LOG(STATE) << "Entering IDLE state"; } }; @@ -122,6 +123,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { + LOG(STATE) << "Entering DEVICE READY state"; fsm.fState = DEVICE_READY; } }; @@ -144,6 +146,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { + LOG(STATE) << "Entering READY state"; fsm.fState = READY; } }; @@ -166,10 +169,10 @@ struct FairMQFSM_ : public msm::front::state_machine_def void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fStateFinished = false; - LOG(STATE) << "Entering PAUSED state"; fsm.fState = PAUSED; fsm.SendCommand("pause"); fsm.fStateThread.join(); + LOG(STATE) << "Entering PAUSED state"; fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::Pause, &fsm)); } }; @@ -195,11 +198,21 @@ struct FairMQFSM_ : public msm::front::state_machine_def { LOG(STATE) << "Received STOP event"; fsm.fState = IDLE; - // fsm.SendCommand("stop"); + fsm.SendCommand("stop"); fsm.fStateThread.join(); } }; + struct InternalStopFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + LOG(STATE) << "RUNNING state finished without an external event"; + fsm.fState = IDLE; + } + }; + struct ResetTaskFct { template @@ -220,7 +233,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def fsm.fStateFinished = false; LOG(STATE) << "Entering RESETTING DEVICE state"; fsm.fState = RESETTING_DEVICE; - fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::ResetWrapper, &fsm)); + fsm.ResetWrapper(); } }; @@ -232,9 +245,9 @@ struct FairMQFSM_ : public msm::front::state_machine_def LOG(STATE) << "Received END event"; fsm.fState = EXITING; - fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::Terminate, &fsm)); + fsm.fTerminateStateThread = boost::thread(boost::bind(&FairMQFSM_::Terminate, &fsm)); fsm.Shutdown(); - fsm.fStateThread.join(); + fsm.fTerminateStateThread.join(); } }; @@ -243,10 +256,13 @@ struct FairMQFSM_ : public msm::front::state_machine_def template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { + LOG(STATE) << "Entering EXITING state"; fsm.fState = EXITING; + fsm.SendCommand("stop"); + fsm.fStateThread.interrupt(); + fsm.fStateThread.join(); fsm.fTerminateStateThread = boost::thread(boost::bind(&FairMQFSM_::Terminate, &fsm)); - fsm.fStateThread.join(); fsm.Shutdown(); fsm.fTerminateStateThread.join(); } @@ -272,27 +288,28 @@ struct FairMQFSM_ : public msm::front::state_machine_def struct transition_table : mpl::vector< // Start Event Next Action Guard // +-------------------------+----------------------+------------------------+---------------+---------+ - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, - msmf::Row, // temporary - msmf::Row > + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, // temporary + msmf::Row > {}; // Replaces the default no-transition response. template void no_transition(Event const& e, FSM&, int state) { - LOG(STATE) << "no transition from state " << GetStateName(state) << " on event " << typeid(e).name(); + LOG(STATE) << "no transition from state " << GetStateName(state) << " on event " << e.name(); } // this is to run certain functions in a separate thread @@ -314,7 +331,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def EXITING }; - std::string GetStateName(int state) + std::string GetStateName(int state) const { switch(state) { @@ -343,14 +360,38 @@ struct FairMQFSM_ : public msm::front::state_machine_def } } - int GetCurrentState() + std::string GetCurrentStateName() const + { + return GetStateName(fState); + } + + int GetCurrentState() const { return fState; } - std::string GetCurrentStateName() + bool CheckCurrentState(int state) const { - return GetStateName(fState); + if (state == fState) + { + return true; + } + else + { + return false; + } + } + + bool CheckCurrentState(std::string state) const + { + if (state == GetCurrentStateName()) + { + return true; + } + else + { + return false; + } } // condition variable to notify parent thread about end of state. @@ -376,7 +417,6 @@ class FairMQStateMachine : public FairMQFSM::FairMQFSM internal_READY, RUN, PAUSE, - RESUME, STOP, RESET_TASK, RESET_DEVICE, diff --git a/fairmq/FairMQTransportFactory.h b/fairmq/FairMQTransportFactory.h index f398fbb6..a956344b 100644 --- a/fairmq/FairMQTransportFactory.h +++ b/fairmq/FairMQTransportFactory.h @@ -23,6 +23,8 @@ #include "FairMQPoller.h" #include "FairMQLogger.h" +class FairMQChannel; + class FairMQTransportFactory { public: @@ -31,6 +33,8 @@ class FairMQTransportFactory virtual FairMQMessage* CreateMessage(void* data, size_t size, fairmq_free_fn *ffn = NULL, void* hint = NULL) = 0; virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, int numIoThreads) = 0; virtual FairMQPoller* CreatePoller(const std::vector& channels) = 0; + virtual FairMQPoller* CreatePoller(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList) = 0; + virtual FairMQPoller* CreatePoller(FairMQSocket& dataSocket, FairMQSocket& cmdSocket) = 0; virtual ~FairMQTransportFactory() {}; }; diff --git a/fairmq/devices/FairMQBenchmarkSampler.cxx b/fairmq/devices/FairMQBenchmarkSampler.cxx index 30a8ea9e..1d53ac07 100644 --- a/fairmq/devices/FairMQBenchmarkSampler.cxx +++ b/fairmq/devices/FairMQBenchmarkSampler.cxx @@ -40,12 +40,15 @@ void FairMQBenchmarkSampler::Run() void* buffer = operator new[](fEventSize); FairMQMessage* baseMsg = fTransportFactory->CreateMessage(buffer, fEventSize); - while (GetCurrentState() == RUNNING) + // store the channel reference to avoid traversing the map on every loop iteration + const FairMQChannel& dataChannel = fChannels.at("data-out").at(0); + + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); msg->Copy(baseMsg); - fChannels["data-out"].at(0).Send(msg); + dataChannel.Send(msg); --fEventCounter; @@ -69,7 +72,7 @@ void FairMQBenchmarkSampler::Run() void FairMQBenchmarkSampler::ResetEventCounter() { - while (GetCurrentState() == RUNNING) + while (CheckCurrentState(RUNNING)) { try { diff --git a/fairmq/devices/FairMQBuffer.cxx b/fairmq/devices/FairMQBuffer.cxx index 5284a22d..c36d49df 100644 --- a/fairmq/devices/FairMQBuffer.cxx +++ b/fairmq/devices/FairMQBuffer.cxx @@ -26,13 +26,17 @@ FairMQBuffer::FairMQBuffer() void FairMQBuffer::Run() { - while (GetCurrentState() == RUNNING) + // store the channel references to avoid traversing the map on every loop iteration + const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); + const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); + + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - if (fChannels["data-in"].at(0).Receive(msg) > 0) + if (dataInChannel.Receive(msg) > 0) { - fChannels["data-out"].at(0).Send(msg); + dataOutChannel.Send(msg); } delete msg; diff --git a/fairmq/devices/FairMQMerger.cxx b/fairmq/devices/FairMQMerger.cxx index a274055d..b8ff6e7c 100644 --- a/fairmq/devices/FairMQMerger.cxx +++ b/fairmq/devices/FairMQMerger.cxx @@ -29,21 +29,38 @@ FairMQMerger::~FairMQMerger() void FairMQMerger::Run() { - FairMQPoller* poller = fTransportFactory->CreatePoller(fChannels["data-in"]); + FairMQPoller* poller = fTransportFactory->CreatePoller(fChannels.at("data-in")); - while (GetCurrentState() == RUNNING) + // store the channel references to avoid traversing the map on every loop iteration + const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); + FairMQChannel* dataInChannels[fChannels.at("data-in").size()]; + for (int i = 0; i < fChannels.at("data-in").size(); ++i) + { + dataInChannels[i] = &(fChannels.at("data-in").at(i)); + } + + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); poller->Poll(100); - for (int i = 0; i < fChannels["data-in"].size(); ++i) + for (int i = 0; i < fChannels.at("data-in").size(); ++i) { if (poller->CheckInput(i)) { - if (fChannels["data-in"].at(i).Receive(msg)) + if (dataInChannels[i]->Receive(msg) > 0) { - fChannels["data-out"].at(0).Send(msg); + if (dataOutChannel.Send(msg) < 0) + { + LOG(DEBUG) << "Blocking send interrupted by a command"; + break; + } + } + else + { + LOG(DEBUG) << "Blocking receive interrupted by a command"; + break; } } } diff --git a/fairmq/devices/FairMQProxy.cxx b/fairmq/devices/FairMQProxy.cxx index f6249168..65cdfc0f 100644 --- a/fairmq/devices/FairMQProxy.cxx +++ b/fairmq/devices/FairMQProxy.cxx @@ -30,11 +30,15 @@ void FairMQProxy::Run() { FairMQMessage* msg = fTransportFactory->CreateMessage(); - while (GetCurrentState() == RUNNING) + // store the channel references to avoid traversing the map on every loop iteration + const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); + const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); + + while (CheckCurrentState(RUNNING)) { - if (fChannels["data-in"].at(0).Receive(msg) > 0) + if (dataInChannel.Receive(msg) > 0) { - fChannels["data-out"].at(0).Send(msg); + dataOutChannel.Send(msg); } } diff --git a/fairmq/devices/FairMQSink.cxx b/fairmq/devices/FairMQSink.cxx index ba50e24b..f3563ead 100644 --- a/fairmq/devices/FairMQSink.cxx +++ b/fairmq/devices/FairMQSink.cxx @@ -24,11 +24,14 @@ FairMQSink::FairMQSink() void FairMQSink::Run() { - while (GetCurrentState() == RUNNING) + // store the channel reference to avoid traversing the map on every loop iteration + const FairMQChannel& dataChannel = fChannels.at("data-in").at(0); + + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - fChannels["data-in"].at(0).Receive(msg); + dataChannel.Receive(msg); delete msg; } diff --git a/fairmq/devices/FairMQSplitter.cxx b/fairmq/devices/FairMQSplitter.cxx index 50385ea1..46ba8f59 100644 --- a/fairmq/devices/FairMQSplitter.cxx +++ b/fairmq/devices/FairMQSplitter.cxx @@ -29,16 +29,25 @@ FairMQSplitter::~FairMQSplitter() void FairMQSplitter::Run() { int direction = 0; + int numOutputs = fChannels.at("data-out").size(); - while (GetCurrentState() == RUNNING) + // store the channel references to avoid traversing the map on every loop iteration + const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); + FairMQChannel* dataOutChannels[fChannels.at("data-out").size()]; + for (int i = 0; i < numOutputs; ++i) + { + dataOutChannels[i] = &(fChannels.at("data-out").at(i)); + } + + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - if (fChannels["data-in"].at(0).Receive(msg) > 0) + if (dataInChannel.Receive(msg) > 0) { - fChannels["data-out"].at(direction).Send(msg); - direction++; - if (direction >= fChannels["data-out"].size()) + dataOutChannels[direction]->Send(msg); + ++direction; + if (direction >= numOutputs) { direction = 0; } diff --git a/fairmq/devices/GenericFileSink.h b/fairmq/devices/GenericFileSink.h index 817a2314..3d00a7dd 100644 --- a/fairmq/devices/GenericFileSink.h +++ b/fairmq/devices/GenericFileSink.h @@ -89,4 +89,3 @@ class GenericFileSink : public FairMQDevice, public InputPolicy, public OutputPo }; #endif /* GENERICFILESINK_H */ - diff --git a/fairmq/devices/GenericFileSink.tpl b/fairmq/devices/GenericFileSink.tpl index 48e11f13..e52d2e7c 100644 --- a/fairmq/devices/GenericFileSink.tpl +++ b/fairmq/devices/GenericFileSink.tpl @@ -44,10 +44,10 @@ void GenericFileSink::Run() { int receivedMsg = 0; - while (GetCurrentState() == RUNNING) + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - if (fChannels["data-in"].at(0).Receive(msg) > 0) + if (fChannels.at("data-in").at(0).Receive(msg) > 0) { OutputPolicy::AddToFile(InputPolicy::DeSerializeMsg(msg)); receivedMsg++; diff --git a/fairmq/devices/GenericProcessor.h b/fairmq/devices/GenericProcessor.h index ebbf0a60..3c80816b 100644 --- a/fairmq/devices/GenericProcessor.h +++ b/fairmq/devices/GenericProcessor.h @@ -92,10 +92,7 @@ class GenericProcessor : public FairMQDevice, public InputPolicy, public OutputP // bool ReceivePart(); bool ReceivePart() { - int64_t more = 0; - size_t more_size = sizeof(more); - fChannels["data-in"].at(0).fSocket->GetOption("rcv-more", &more, &more_size); - if (more) + if (fChannels["data-in"].at(0).ExpectsAnotherPart()) { InputPolicy::CloseMessage(); // fProcessorTask->GetPayload()->CloseMessage(); @@ -123,7 +120,7 @@ class GenericProcessor : public FairMQDevice, public InputPolicy, public OutputP int receivedMsgs = 0; int sentMsgs = 0; - while (GetCurrentState() == RUNNING) + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); diff --git a/fairmq/devices/GenericSampler.tpl b/fairmq/devices/GenericSampler.tpl index ba61f5c1..8ec3587b 100644 --- a/fairmq/devices/GenericSampler.tpl +++ b/fairmq/devices/GenericSampler.tpl @@ -51,8 +51,9 @@ void base_GenericSampler::Run() boost::timer::auto_cpu_timer timer; LOG(INFO) << "Number of events to process: " << fNumEvents; - - do { + + do + { for (fCurrentIdx = 0; fCurrentIdx < fNumEvents; fCurrentIdx++) { for(auto& p : fChannels[fOutChanName]) @@ -75,7 +76,7 @@ void base_GenericSampler::Run() // boost::this_thread::sleep(boost::posix_time::milliseconds(1)); // } - if (GetCurrentState() != RUNNING) + if (!CheckCurrentState(RUNNING)) break; } // if more than one socket, remove the last incrementation @@ -83,7 +84,7 @@ void base_GenericSampler::Run() fCurrentIdx--; } } - while ( GetCurrentState() == RUNNING && fContinuous ); + while (CheckCurrentState(RUNNING) && fContinuous); boost::timer::cpu_times const elapsed_time(timer.elapsed()); LOG(INFO) << "Sent everything in:\n" << boost::timer::format(elapsed_time, 2); diff --git a/fairmq/examples/1-sampler-sink/FairMQExample1Sampler.cxx b/fairmq/examples/1-sampler-sink/FairMQExample1Sampler.cxx index 30f605c0..828178d4 100644 --- a/fairmq/examples/1-sampler-sink/FairMQExample1Sampler.cxx +++ b/fairmq/examples/1-sampler-sink/FairMQExample1Sampler.cxx @@ -40,7 +40,7 @@ void FairMQExample1Sampler::Run() LOG(INFO) << "Sending \"" << fText << "\""; - fChannels["data-out"].at(0).Send(msg); + fChannels.at("data-out").at(0).Send(msg); } } diff --git a/fairmq/examples/1-sampler-sink/FairMQExample1Sink.cxx b/fairmq/examples/1-sampler-sink/FairMQExample1Sink.cxx index 1a3799a8..dfc173ff 100644 --- a/fairmq/examples/1-sampler-sink/FairMQExample1Sink.cxx +++ b/fairmq/examples/1-sampler-sink/FairMQExample1Sink.cxx @@ -30,7 +30,7 @@ void FairMQExample1Sink::Run() { FairMQMessage* msg = fTransportFactory->CreateMessage(); - fChannels["data-in"].at(0).Receive(msg); + fChannels.at("data-in").at(0).Receive(msg); LOG(INFO) << "Received message: \"" << string(static_cast(msg->GetData()), msg->GetSize()) diff --git a/fairmq/examples/1-sampler-sink/runExample1Sampler.cxx b/fairmq/examples/1-sampler-sink/runExample1Sampler.cxx index 3e07087a..d1b69ec5 100644 --- a/fairmq/examples/1-sampler-sink/runExample1Sampler.cxx +++ b/fairmq/examples/1-sampler-sink/runExample1Sampler.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -30,31 +29,10 @@ using namespace boost::program_options; -FairMQExample1Sampler sampler; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sampler.ChangeState("END"); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExample1Sampler sampler; + sampler.CatchSignals(); FairMQProgOptions config; @@ -100,18 +78,7 @@ int main(int argc, char** argv) sampler.WaitForEndOfState("INIT_TASK"); sampler.ChangeState("RUN"); - sampler.WaitForEndOfState("RUN"); - - sampler.ChangeState("STOP"); - - sampler.ChangeState("RESET_TASK"); - sampler.WaitForEndOfState("RESET_TASK"); - - sampler.ChangeState("RESET_DEVICE"); - sampler.WaitForEndOfState("RESET_DEVICE"); - - sampler.ChangeState("END"); - + sampler.InteractiveStateLoop(); } catch (std::exception& e) { diff --git a/fairmq/examples/1-sampler-sink/runExample1Sink.cxx b/fairmq/examples/1-sampler-sink/runExample1Sink.cxx index 4da79658..4779c7f1 100644 --- a/fairmq/examples/1-sampler-sink/runExample1Sink.cxx +++ b/fairmq/examples/1-sampler-sink/runExample1Sink.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -30,31 +29,10 @@ using namespace boost::program_options; -FairMQExample1Sink sink; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sink.ChangeState(FairMQExample1Sink::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExample1Sink sink; + sink.CatchSignals(); FairMQProgOptions config; @@ -91,18 +69,7 @@ int main(int argc, char** argv) sink.WaitForEndOfState("INIT_TASK"); sink.ChangeState("RUN"); - sink.WaitForEndOfState("RUN"); - - sink.ChangeState("STOP"); - - sink.ChangeState("RESET_TASK"); - sink.WaitForEndOfState("RESET_TASK"); - - sink.ChangeState("RESET_DEVICE"); - sink.WaitForEndOfState("RESET_DEVICE"); - - sink.ChangeState("END"); - + sink.InteractiveStateLoop(); } catch (std::exception& e) { diff --git a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Processor.cxx b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Processor.cxx index 57b6a4fd..4987076a 100644 --- a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Processor.cxx +++ b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Processor.cxx @@ -33,7 +33,7 @@ void FairMQExample2Processor::Run() while (GetCurrentState() == RUNNING) { FairMQMessage* input = fTransportFactory->CreateMessage(); - fChannels["data-in"].at(0).Receive(input); + fChannels.at("data-in").at(0).Receive(input); LOG(INFO) << "Received data, processing..."; @@ -43,7 +43,7 @@ void FairMQExample2Processor::Run() delete input; FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast(text->c_str()), text->length(), CustomCleanup, text); - fChannels["data-out"].at(0).Send(msg); + fChannels.at("data-out").at(0).Send(msg); } } diff --git a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sampler.cxx b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sampler.cxx index 03215b48..74d96eb0 100644 --- a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sampler.cxx +++ b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sampler.cxx @@ -40,7 +40,7 @@ void FairMQExample2Sampler::Run() LOG(INFO) << "Sending \"" << fText << "\""; - fChannels["data-out"].at(0).Send(msg); + fChannels.at("data-out").at(0).Send(msg); } } diff --git a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sink.cxx b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sink.cxx index 96953b28..53058518 100644 --- a/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sink.cxx +++ b/fairmq/examples/2-sampler-processor-sink/FairMQExample2Sink.cxx @@ -30,7 +30,7 @@ void FairMQExample2Sink::Run() { FairMQMessage* msg = fTransportFactory->CreateMessage(); - fChannels["data-in"].at(0).Receive(msg); + fChannels.at("data-in").at(0).Receive(msg); LOG(INFO) << "Received message: \"" << string(static_cast(msg->GetData()), msg->GetSize()) diff --git a/fairmq/examples/2-sampler-processor-sink/runExample2Processor.cxx b/fairmq/examples/2-sampler-processor-sink/runExample2Processor.cxx index 1b9c180b..0b390172 100644 --- a/fairmq/examples/2-sampler-processor-sink/runExample2Processor.cxx +++ b/fairmq/examples/2-sampler-processor-sink/runExample2Processor.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -30,31 +29,10 @@ using namespace boost::program_options; -FairMQExample2Processor processor; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - processor.ChangeState("END"); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExample2Processor processor; + processor.CatchSignals(); FairMQProgOptions config; @@ -91,18 +69,7 @@ int main(int argc, char** argv) processor.WaitForEndOfState("INIT_TASK"); processor.ChangeState("RUN"); - processor.WaitForEndOfState("RUN"); - - processor.ChangeState("STOP"); - - processor.ChangeState("RESET_TASK"); - processor.WaitForEndOfState("RESET_TASK"); - - processor.ChangeState("RESET_DEVICE"); - processor.WaitForEndOfState("RESET_DEVICE"); - - processor.ChangeState("END"); - + processor.InteractiveStateLoop(); } catch (std::exception& e) { diff --git a/fairmq/examples/2-sampler-processor-sink/runExample2Sampler.cxx b/fairmq/examples/2-sampler-processor-sink/runExample2Sampler.cxx index 72e9507f..b76f3a42 100644 --- a/fairmq/examples/2-sampler-processor-sink/runExample2Sampler.cxx +++ b/fairmq/examples/2-sampler-processor-sink/runExample2Sampler.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -30,31 +29,10 @@ using namespace boost::program_options; -FairMQExample2Sampler sampler; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sampler.ChangeState("END"); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExample2Sampler sampler; + sampler.CatchSignals(); FairMQProgOptions config; @@ -100,18 +78,7 @@ int main(int argc, char** argv) sampler.WaitForEndOfState("INIT_TASK"); sampler.ChangeState("RUN"); - sampler.WaitForEndOfState("RUN"); - - sampler.ChangeState("STOP"); - - sampler.ChangeState("RESET_TASK"); - sampler.WaitForEndOfState("RESET_TASK"); - - sampler.ChangeState("RESET_DEVICE"); - sampler.WaitForEndOfState("RESET_DEVICE"); - - sampler.ChangeState("END"); - + sampler.InteractiveStateLoop(); } catch (std::exception& e) { diff --git a/fairmq/examples/2-sampler-processor-sink/runExample2Sink.cxx b/fairmq/examples/2-sampler-processor-sink/runExample2Sink.cxx index 9d1c39e8..312d703b 100644 --- a/fairmq/examples/2-sampler-processor-sink/runExample2Sink.cxx +++ b/fairmq/examples/2-sampler-processor-sink/runExample2Sink.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -30,31 +29,10 @@ using namespace boost::program_options; -FairMQExample2Sink sink; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sink.ChangeState(FairMQExample2Sink::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExample2Sink sink; + sink.CatchSignals(); FairMQProgOptions config; @@ -91,18 +69,7 @@ int main(int argc, char** argv) sink.WaitForEndOfState("INIT_TASK"); sink.ChangeState("RUN"); - sink.WaitForEndOfState("RUN"); - - sink.ChangeState("STOP"); - - sink.ChangeState("RESET_TASK"); - sink.WaitForEndOfState("RESET_TASK"); - - sink.ChangeState("RESET_DEVICE"); - sink.WaitForEndOfState("RESET_DEVICE"); - - sink.ChangeState("END"); - + sink.InteractiveStateLoop(); } catch (std::exception& e) { diff --git a/fairmq/examples/req-rep/FairMQExampleClient.cxx b/fairmq/examples/req-rep/FairMQExampleClient.cxx index 8f24e0cd..ea19aa56 100644 --- a/fairmq/examples/req-rep/FairMQExampleClient.cxx +++ b/fairmq/examples/req-rep/FairMQExampleClient.cxx @@ -47,8 +47,8 @@ void FairMQExampleClient::Run() LOG(INFO) << "Sending \"" << fText << "\" to server."; - fChannels["data"].at(0).Send(request); - fChannels["data"].at(0).Receive(reply); + fChannels.at("data").at(0).Send(request); + fChannels.at("data").at(0).Receive(reply); LOG(INFO) << "Received reply from server: \"" << string(static_cast(reply->GetData()), reply->GetSize()) << "\""; diff --git a/fairmq/examples/req-rep/FairMQExampleServer.cxx b/fairmq/examples/req-rep/FairMQExampleServer.cxx index 4a740e34..2bd3730c 100644 --- a/fairmq/examples/req-rep/FairMQExampleServer.cxx +++ b/fairmq/examples/req-rep/FairMQExampleServer.cxx @@ -37,7 +37,7 @@ void FairMQExampleServer::Run() FairMQMessage* request = fTransportFactory->CreateMessage(); - fChannels["data"].at(0).Receive(request); + fChannels.at("data").at(0).Receive(request); LOG(INFO) << "Received request from client: \"" << string(static_cast(request->GetData()), request->GetSize()) << "\""; @@ -49,7 +49,7 @@ void FairMQExampleServer::Run() FairMQMessage* reply = fTransportFactory->CreateMessage(const_cast(text->c_str()), text->length(), CustomCleanup, text); - fChannels["data"].at(0).Send(reply); + fChannels.at("data").at(0).Send(reply); } } diff --git a/fairmq/examples/req-rep/runExampleClient.cxx b/fairmq/examples/req-rep/runExampleClient.cxx index de29cf43..c257f840 100644 --- a/fairmq/examples/req-rep/runExampleClient.cxx +++ b/fairmq/examples/req-rep/runExampleClient.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,28 +27,6 @@ using namespace std; -FairMQExampleClient client; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - client.ChangeState(FairMQExampleClient::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -72,7 +49,7 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) bpo::variables_map vm; bpo::store(bpo::parse_command_line(_argc, _argv, desc), vm); - if ( vm.count("help") ) + if (vm.count("help")) { LOG(INFO) << "EPN" << endl << desc; return false; @@ -88,7 +65,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQExampleClient client; + client.CatchSignals(); DeviceOptions_t options; try @@ -122,24 +100,14 @@ int main(int argc, char** argv) client.fChannels["data"].push_back(requestChannel); - client.ChangeState(FairMQExampleClient::INIT_DEVICE); - client.WaitForEndOfState(FairMQExampleClient::INIT_DEVICE); + client.ChangeState("INIT_DEVICE"); + client.WaitForEndOfState("INIT_DEVICE"); - client.ChangeState(FairMQExampleClient::INIT_TASK); - client.WaitForEndOfState(FairMQExampleClient::INIT_TASK); + client.ChangeState("INIT_TASK"); + client.WaitForEndOfState("INIT_TASK"); - client.ChangeState(FairMQExampleClient::RUN); - client.WaitForEndOfState(FairMQExampleClient::RUN); - - client.ChangeState(FairMQExampleClient::STOP); - - client.ChangeState(FairMQExampleClient::RESET_TASK); - client.WaitForEndOfState(FairMQExampleClient::RESET_TASK); - - client.ChangeState(FairMQExampleClient::RESET_DEVICE); - client.WaitForEndOfState(FairMQExampleClient::RESET_DEVICE); - - client.ChangeState(FairMQExampleClient::END); + client.ChangeState("RUN"); + client.InteractiveStateLoop(); return 0; } diff --git a/fairmq/examples/req-rep/runExampleServer.cxx b/fairmq/examples/req-rep/runExampleServer.cxx index d4f868ab..a83d156d 100644 --- a/fairmq/examples/req-rep/runExampleServer.cxx +++ b/fairmq/examples/req-rep/runExampleServer.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "FairMQLogger.h" #include "FairMQExampleServer.h" @@ -26,31 +25,10 @@ using namespace std; -FairMQExampleServer server; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - server.ChangeState(FairMQExampleServer::END); - - LOG(INFO) << "Caught signal " << signal; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQExampleServer server; + server.CatchSignals(); LOG(INFO) << "PID: " << getpid(); @@ -72,24 +50,14 @@ int main(int argc, char** argv) server.fChannels["data"].push_back(replyChannel); - server.ChangeState(FairMQExampleServer::INIT_DEVICE); - server.WaitForEndOfState(FairMQExampleServer::INIT_DEVICE); + server.ChangeState("INIT_DEVICE"); + server.WaitForEndOfState("INIT_DEVICE"); - server.ChangeState(FairMQExampleServer::INIT_TASK); - server.WaitForEndOfState(FairMQExampleServer::INIT_TASK); + server.ChangeState("INIT_TASK"); + server.WaitForEndOfState("INIT_TASK"); - server.ChangeState(FairMQExampleServer::RUN); - server.WaitForEndOfState(FairMQExampleServer::RUN); - - server.ChangeState(FairMQExampleServer::STOP); - - server.ChangeState(FairMQExampleServer::RESET_TASK); - server.WaitForEndOfState(FairMQExampleServer::RESET_TASK); - - server.ChangeState(FairMQExampleServer::RESET_DEVICE); - server.WaitForEndOfState(FairMQExampleServer::RESET_DEVICE); - - server.ChangeState(FairMQExampleServer::END); + server.ChangeState("RUN"); + server.InteractiveStateLoop(); return 0; } diff --git a/fairmq/nanomsg/FairMQPollerNN.cxx b/fairmq/nanomsg/FairMQPollerNN.cxx index e6659438..1c4b5a15 100644 --- a/fairmq/nanomsg/FairMQPollerNN.cxx +++ b/fairmq/nanomsg/FairMQPollerNN.cxx @@ -13,6 +13,10 @@ */ #include +#include +#include +#include +#include #include "FairMQPollerNN.h" #include "FairMQLogger.h" @@ -21,7 +25,8 @@ using namespace std; FairMQPollerNN::FairMQPollerNN(const vector& channels) : items() - , fNumItems() + , fNumItems(0) + , fOffsetMap() { fNumItems = channels.size(); items = new nn_pollfd[fNumItems]; @@ -33,15 +38,95 @@ FairMQPollerNN::FairMQPollerNN(const vector& channels) } } +FairMQPollerNN::FairMQPollerNN(map< string,vector >& channelsMap, initializer_list channelList) + : items() + , fNumItems(0) + , fOffsetMap() +{ + int offset = 0; + + try + { + // calculate offsets and the total size of the poll item set + for (string channel : channelList) + { + fOffsetMap[channel] = offset; + offset += channelsMap.at(channel).size(); + fNumItems += channelsMap.at(channel).size(); + } + + items = new nn_pollfd[fNumItems]; + + int index = 0; + for (string channel : channelList) + { + for (int i = 0; i < channelsMap.at(channel).size(); ++i) + { + index = fOffsetMap[channel] + i; + items[index].fd = channelsMap.at(channel).at(i).fSocket->GetSocket(1); + items[index].events = NN_POLLIN; + } + } + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "At least one of the provided channel keys for poller initialization is invalid"; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); + } +} + +FairMQPollerNN::FairMQPollerNN(FairMQSocket& dataSocket, FairMQSocket& cmdSocket) + : items() + , fNumItems(2) + , fOffsetMap() +{ + items = new nn_pollfd[fNumItems]; + + items[0].fd = cmdSocket.GetSocket(1); + items[0].events = NN_POLLIN; + + int type = 0; + size_t sz = sizeof(type); + nn_getsockopt(dataSocket.GetSocket(1), NN_SOL_SOCKET, NN_PROTOCOL, &type, &sz); + + items[1].fd = dataSocket.GetSocket(1); + + if (type == NN_REQ || type == NN_REP || type == NN_PAIR) + { + items[1].events = NN_POLLIN|NN_POLLOUT; + } + else if (type == NN_PUSH || type == NN_PUB) + { + items[1].events = NN_POLLOUT; + } + else if (type == NN_PULL || type == NN_SUB) + { + items[1].events = NN_POLLIN; + } + else + { + LOG(ERROR) << "invalid poller configuration, exiting."; + exit(EXIT_FAILURE); + } +} + void FairMQPollerNN::Poll(int timeout) { if (nn_poll(items, fNumItems, timeout) < 0) { - LOG(ERROR) << "polling failed, reason: " << nn_strerror(errno); + if (errno == ETERM) + { + LOG(DEBUG) << "polling exited, reason: " << nn_strerror(errno); + } + else + { + LOG(ERROR) << "polling failed, reason: " << nn_strerror(errno); + } } } -bool FairMQPollerNN::CheckInput(int index) +bool FairMQPollerNN::CheckInput(const int index) { if (items[index].revents & NN_POLLIN) { @@ -51,7 +136,7 @@ bool FairMQPollerNN::CheckInput(int index) return false; } -bool FairMQPollerNN::CheckOutput(int index) +bool FairMQPollerNN::CheckOutput(const int index) { if (items[index].revents & NN_POLLOUT) { @@ -61,6 +146,44 @@ bool FairMQPollerNN::CheckOutput(int index) return false; } +bool FairMQPollerNN::CheckInput(const string channelKey, const int index) +{ + try + { + if (items[fOffsetMap.at(channelKey) + index].revents & NN_POLLIN) + { + return true; + } + + return false; + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\""; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); + } +} + +bool FairMQPollerNN::CheckOutput(const string channelKey, const int index) +{ + try + { + if (items[fOffsetMap.at(channelKey) + index].revents & NN_POLLOUT) + { + return true; + } + + return false; + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\""; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); + } +} + FairMQPollerNN::~FairMQPollerNN() { if (items != NULL) diff --git a/fairmq/nanomsg/FairMQPollerNN.h b/fairmq/nanomsg/FairMQPollerNN.h index ba146b10..c4df2793 100644 --- a/fairmq/nanomsg/FairMQPollerNN.h +++ b/fairmq/nanomsg/FairMQPollerNN.h @@ -16,25 +16,40 @@ #define FAIRMQPOLLERNN_H_ #include +#include +#include #include "FairMQPoller.h" #include "FairMQChannel.h" +#include "FairMQTransportFactoryNN.h" + +class FairMQChannel; class FairMQPollerNN : public FairMQPoller { + friend class FairMQChannel; + friend class FairMQTransportFactoryNN; + public: FairMQPollerNN(const std::vector& channels); + FairMQPollerNN(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList); - virtual void Poll(int timeout); - virtual bool CheckInput(int index); - virtual bool CheckOutput(int index); + virtual void Poll(const int timeout); + virtual bool CheckInput(const int index); + virtual bool CheckOutput(const int index); + virtual bool CheckInput(const std::string channelKey, const int index); + virtual bool CheckOutput(const std::string channelKey, const int index); virtual ~FairMQPollerNN(); private: + FairMQPollerNN(FairMQSocket& dataSocket, FairMQSocket& cmdSocket); + nn_pollfd* items; int fNumItems; + std::unordered_map fOffsetMap; + /// Copy Constructor FairMQPollerNN(const FairMQPollerNN&); FairMQPollerNN operator=(const FairMQPollerNN&); diff --git a/fairmq/nanomsg/FairMQSocketNN.cxx b/fairmq/nanomsg/FairMQSocketNN.cxx index d5f0a591..9e478a3e 100644 --- a/fairmq/nanomsg/FairMQSocketNN.cxx +++ b/fairmq/nanomsg/FairMQSocketNN.cxx @@ -22,7 +22,7 @@ using namespace std; FairMQSocketNN::FairMQSocketNN(const string& type, const std::string& name, int numIoThreads) : FairMQSocket(0, 0, NN_DONTWAIT) - , fSocket() + , fSocket(-1) , fId() , fBytesTx(0) , fBytesRx(0) diff --git a/fairmq/nanomsg/FairMQTransportFactoryNN.cxx b/fairmq/nanomsg/FairMQTransportFactoryNN.cxx index 63ff874b..6080a505 100644 --- a/fairmq/nanomsg/FairMQTransportFactoryNN.cxx +++ b/fairmq/nanomsg/FairMQTransportFactoryNN.cxx @@ -45,3 +45,13 @@ FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const vector { return new FairMQPollerNN(channels); } + +FairMQPoller* FairMQTransportFactoryNN::CreatePoller(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList) +{ + return new FairMQPollerNN(channelsMap, channelList); +} + +FairMQPoller* FairMQTransportFactoryNN::CreatePoller(FairMQSocket& dataSocket, FairMQSocket& cmdSocket) +{ + return new FairMQPollerNN(dataSocket, cmdSocket); +} diff --git a/fairmq/nanomsg/FairMQTransportFactoryNN.h b/fairmq/nanomsg/FairMQTransportFactoryNN.h index 973a9831..a41acb01 100644 --- a/fairmq/nanomsg/FairMQTransportFactoryNN.h +++ b/fairmq/nanomsg/FairMQTransportFactoryNN.h @@ -30,8 +30,12 @@ class FairMQTransportFactoryNN : public FairMQTransportFactory virtual FairMQMessage* CreateMessage(); virtual FairMQMessage* CreateMessage(size_t size); virtual FairMQMessage* CreateMessage(void* data, size_t size, fairmq_free_fn *ffn = NULL, void* hint = NULL); + virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, int numIoThreads); + virtual FairMQPoller* CreatePoller(const std::vector& channels); + virtual FairMQPoller* CreatePoller(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList); + virtual FairMQPoller* CreatePoller(FairMQSocket& dataSocket, FairMQSocket& cmdSocket); virtual ~FairMQTransportFactoryNN() {}; }; diff --git a/fairmq/options/FairMQParser.h b/fairmq/options/FairMQParser.h index 66460507..f31a95e8 100644 --- a/fairmq/options/FairMQParser.h +++ b/fairmq/options/FairMQParser.h @@ -12,6 +12,7 @@ #include #include #include +#include // Boost #include @@ -22,7 +23,7 @@ namespace FairMQParser { -typedef std::map< std::string,std::vector > FairMQMap; +typedef std::unordered_map< std::string,std::vector > FairMQMap; FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag = "json"); diff --git a/fairmq/options/FairMQProgOptions.h b/fairmq/options/FairMQProgOptions.h index 8ac2f07c..f74c05da 100644 --- a/fairmq/options/FairMQProgOptions.h +++ b/fairmq/options/FairMQProgOptions.h @@ -16,6 +16,8 @@ #ifndef FAIRMQPROGOPTIONS_H #define FAIRMQPROGOPTIONS_H +#include + #include "FairProgOptions.h" #include "FairMQChannel.h" @@ -25,7 +27,7 @@ namespace pt = boost::property_tree; class FairMQProgOptions : public FairProgOptions { protected: - typedef std::map< std::string,std::vector > FairMQMap; + typedef std::unordered_map< std::string,std::vector > FairMQMap; public: FairMQProgOptions(); diff --git a/fairmq/prototest/FairMQBinSampler.cxx b/fairmq/prototest/FairMQBinSampler.cxx index 1a2507f5..9f50957f 100644 --- a/fairmq/prototest/FairMQBinSampler.cxx +++ b/fairmq/prototest/FairMQBinSampler.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -22,6 +22,8 @@ #include "FairMQBinSampler.h" #include "FairMQLogger.h" +using namespace std; + FairMQBinSampler::FairMQBinSampler() : fEventSize(10000) , fEventRate(1) @@ -33,25 +35,18 @@ FairMQBinSampler::~FairMQBinSampler() { } -void FairMQBinSampler::Init() -{ -} - void FairMQBinSampler::Run() { - LOG(INFO) << ">>>>>>> Run <<<<<<<"; - // boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); - - boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread resetEventCounter(boost::bind(&FairMQBinSampler::ResetEventCounter, this)); srand(time(NULL)); LOG(DEBUG) << "Message size: " << fEventSize * sizeof(Content) << " bytes."; - while (fState == RUNNING) - { + const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); + while (CheckCurrentState(RUNNING)) + { Content* payload = new Content[fEventSize]; for (int i = 0; i < fEventSize; ++i) @@ -67,7 +62,7 @@ void FairMQBinSampler::Run() FairMQMessage* msg = fTransportFactory->CreateMessage(fEventSize * sizeof(Content)); memcpy(msg->GetData(), payload, fEventSize * sizeof(Content)); - fPayloadOutputs->at(0)->Send(msg); + dataOutChannel.Send(msg); --fEventCounter; @@ -80,16 +75,13 @@ void FairMQBinSampler::Run() delete msg; } - rateLogger.interrupt(); resetEventCounter.interrupt(); - - rateLogger.join(); resetEventCounter.join(); } void FairMQBinSampler::ResetEventCounter() { - while (true) + while (GetCurrentState() == RUNNING) { try { @@ -103,61 +95,26 @@ void FairMQBinSampler::ResetEventCounter() } } -void FairMQBinSampler::Log(int intervalInMs) -{ - timestamp_t t0; - timestamp_t t1; - unsigned long bytes = fPayloadOutputs->at(0)->GetBytesTx(); - unsigned long messages = fPayloadOutputs->at(0)->GetMessagesTx(); - unsigned long bytesNew = 0; - unsigned long messagesNew = 0; - double megabytesPerSecond = 0; - double messagesPerSecond = 0; - - t0 = get_timestamp(); - - while (true) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(intervalInMs)); - - t1 = get_timestamp(); - - bytesNew = fPayloadOutputs->at(0)->GetBytesTx(); - messagesNew = fPayloadOutputs->at(0)->GetMessagesTx(); - - timestamp_t timeSinceLastLog_ms = (t1 - t0) / 1000.0L; - - megabytesPerSecond = ((double)(bytesNew - bytes) / (1024. * 1024.)) / (double)timeSinceLastLog_ms * 1000.; - messagesPerSecond = (double)(messagesNew - messages) / (double)timeSinceLastLog_ms * 1000.; - - LOG(DEBUG) << "send " << messagesPerSecond << " msg/s, " << megabytesPerSecond << " MB/s"; - - bytes = bytesNew; - messages = messagesNew; - t0 = t1; - } -} - -void FairMQBinSampler::SetProperty(const int key, const string& value, const int slot /*= 0*/) +void FairMQBinSampler::SetProperty(const int key, const string& value) { switch (key) { default: - FairMQDevice::SetProperty(key, value, slot); + FairMQDevice::SetProperty(key, value); break; } } -string FairMQBinSampler::GetProperty(const int key, const string& default_ /*= ""*/, const int slot /*= 0*/) +string FairMQBinSampler::GetProperty(const int key, const string& default_ /*= ""*/) { switch (key) { default: - return FairMQDevice::GetProperty(key, default_, slot); + return FairMQDevice::GetProperty(key, default_); } } -void FairMQBinSampler::SetProperty(const int key, const int value, const int slot /*= 0*/) +void FairMQBinSampler::SetProperty(const int key, const int value) { switch (key) { @@ -168,12 +125,12 @@ void FairMQBinSampler::SetProperty(const int key, const int value, const int slo fEventRate = value; break; default: - FairMQDevice::SetProperty(key, value, slot); + FairMQDevice::SetProperty(key, value); break; } } -int FairMQBinSampler::GetProperty(const int key, const int default_ /*= 0*/, const int slot /*= 0*/) +int FairMQBinSampler::GetProperty(const int key, const int default_ /*= 0*/) { switch (key) { @@ -182,6 +139,6 @@ int FairMQBinSampler::GetProperty(const int key, const int default_ /*= 0*/, con case EventRate: return fEventRate; default: - return FairMQDevice::GetProperty(key, default_, slot); + return FairMQDevice::GetProperty(key, default_); } } diff --git a/fairmq/prototest/FairMQBinSampler.h b/fairmq/prototest/FairMQBinSampler.h index 51c4a3c4..31c30ebb 100644 --- a/fairmq/prototest/FairMQBinSampler.h +++ b/fairmq/prototest/FairMQBinSampler.h @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -33,25 +33,25 @@ class FairMQBinSampler : public FairMQDevice public: enum { - InputFile = FairMQDevice::Last, - EventRate, + EventRate = FairMQDevice::Last, EventSize, Last }; FairMQBinSampler(); virtual ~FairMQBinSampler(); - void Log(int intervalInMs); + void ResetEventCounter(); - virtual void SetProperty(const int key, const string& value, const int slot = 0); - virtual string GetProperty(const int key, const string& default_ = "", const int slot = 0); - virtual void SetProperty(const int key, const int value, const int slot = 0); - virtual int GetProperty(const int key, const int default_ = 0, const int slot = 0); + + virtual void SetProperty(const int key, const std::string& value); + virtual std::string GetProperty(const int key, const std::string& default_ = ""); + virtual void SetProperty(const int key, const int value); + virtual int GetProperty(const int key, const int default_ = 0); protected: int fEventSize; int fEventRate; int fEventCounter; - virtual void Init(); + virtual void Run(); }; diff --git a/fairmq/prototest/FairMQBinSink.cxx b/fairmq/prototest/FairMQBinSink.cxx index 9163b956..e1061f45 100644 --- a/fairmq/prototest/FairMQBinSink.cxx +++ b/fairmq/prototest/FairMQBinSink.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -24,15 +24,13 @@ FairMQBinSink::FairMQBinSink() void FairMQBinSink::Run() { - LOG(INFO) << ">>>>>>> Run <<<<<<<"; + const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); - boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); - - while (fState == RUNNING) + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - fPayloadInputs->at(0)->Receive(msg); + dataInChannel.Receive(msg); int inputSize = msg->GetSize(); // int numInput = inputSize / sizeof(Content); @@ -44,9 +42,6 @@ void FairMQBinSink::Run() delete msg; } - - rateLogger.interrupt(); - rateLogger.join(); } FairMQBinSink::~FairMQBinSink() diff --git a/fairmq/prototest/FairMQBinSink.h b/fairmq/prototest/FairMQBinSink.h index 008e75c9..030b1403 100644 --- a/fairmq/prototest/FairMQBinSink.h +++ b/fairmq/prototest/FairMQBinSink.h @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** diff --git a/fairmq/prototest/FairMQProtoSampler.cxx b/fairmq/prototest/FairMQProtoSampler.cxx index 7677384e..6c85ac46 100644 --- a/fairmq/prototest/FairMQProtoSampler.cxx +++ b/fairmq/prototest/FairMQProtoSampler.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -35,23 +35,16 @@ FairMQProtoSampler::~FairMQProtoSampler() { } -void FairMQProtoSampler::Init() -{ -} - void FairMQProtoSampler::Run() { - LOG(INFO) << ">>>>>>> Run <<<<<<<"; - // boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); - - boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread resetEventCounter(boost::bind(&FairMQProtoSampler::ResetEventCounter, this)); srand(time(NULL)); - while (fState == RUNNING) - { + const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); + while (CheckCurrentState(RUNNING)) + { sampler::Payload p; for (int i = 0; i < fEventSize; ++i) @@ -73,7 +66,7 @@ void FairMQProtoSampler::Run() FairMQMessage* msg = fTransportFactory->CreateMessage(size); memcpy(msg->GetData(), str.c_str(), size); - fPayloadOutputs->at(0)->Send(msg); + dataOutChannel.Send(msg); --fEventCounter; @@ -85,10 +78,7 @@ void FairMQProtoSampler::Run() delete msg; } - rateLogger.interrupt(); resetEventCounter.interrupt(); - - rateLogger.join(); resetEventCounter.join(); } @@ -108,61 +98,26 @@ void FairMQProtoSampler::ResetEventCounter() } } -void FairMQProtoSampler::Log(int intervalInMs) -{ - timestamp_t t0; - timestamp_t t1; - unsigned long bytes = fPayloadOutputs->at(0)->GetBytesTx(); - unsigned long messages = fPayloadOutputs->at(0)->GetMessagesTx(); - unsigned long bytesNew = 0; - unsigned long messagesNew = 0; - double megabytesPerSecond = 0; - double messagesPerSecond = 0; - - t0 = get_timestamp(); - - while (true) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(intervalInMs)); - - t1 = get_timestamp(); - - bytesNew = fPayloadOutputs->at(0)->GetBytesTx(); - messagesNew = fPayloadOutputs->at(0)->GetMessagesTx(); - - timestamp_t timeSinceLastLog_ms = (t1 - t0) / 1000.0L; - - megabytesPerSecond = ((double)(bytesNew - bytes) / (1024. * 1024.)) / (double)timeSinceLastLog_ms * 1000.; - messagesPerSecond = (double)(messagesNew - messages) / (double)timeSinceLastLog_ms * 1000.; - - LOG(DEBUG) << "send " << messagesPerSecond << " msg/s, " << megabytesPerSecond << " MB/s"; - - bytes = bytesNew; - messages = messagesNew; - t0 = t1; - } -} - -void FairMQProtoSampler::SetProperty(const int key, const string& value, const int slot /*= 0*/) +void FairMQProtoSampler::SetProperty(const int key, const string& value) { switch (key) { default: - FairMQDevice::SetProperty(key, value, slot); + FairMQDevice::SetProperty(key, value); break; } } -string FairMQProtoSampler::GetProperty(const int key, const string& default_ /*= ""*/, const int slot /*= 0*/) +string FairMQProtoSampler::GetProperty(const int key, const string& default_ /*= ""*/) { switch (key) { default: - return FairMQDevice::GetProperty(key, default_, slot); + return FairMQDevice::GetProperty(key, default_); } } -void FairMQProtoSampler::SetProperty(const int key, const int value, const int slot /*= 0*/) +void FairMQProtoSampler::SetProperty(const int key, const int value) { switch (key) { @@ -173,12 +128,12 @@ void FairMQProtoSampler::SetProperty(const int key, const int value, const int s fEventRate = value; break; default: - FairMQDevice::SetProperty(key, value, slot); + FairMQDevice::SetProperty(key, value); break; } } -int FairMQProtoSampler::GetProperty(const int key, const int default_ /*= 0*/, const int slot /*= 0*/) +int FairMQProtoSampler::GetProperty(const int key, const int default_ /*= 0*/) { switch (key) { @@ -187,6 +142,6 @@ int FairMQProtoSampler::GetProperty(const int key, const int default_ /*= 0*/, c case EventRate: return fEventRate; default: - return FairMQDevice::GetProperty(key, default_, slot); + return FairMQDevice::GetProperty(key, default_); } } diff --git a/fairmq/prototest/FairMQProtoSampler.h b/fairmq/prototest/FairMQProtoSampler.h index be08284c..57c7a1ac 100644 --- a/fairmq/prototest/FairMQProtoSampler.h +++ b/fairmq/prototest/FairMQProtoSampler.h @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -24,25 +24,25 @@ class FairMQProtoSampler : public FairMQDevice public: enum { - InputFile = FairMQDevice::Last, - EventRate, + EventRate = FairMQDevice::Last, EventSize, Last }; FairMQProtoSampler(); virtual ~FairMQProtoSampler(); - void Log(int intervalInMs); + void ResetEventCounter(); - virtual void SetProperty(const int key, const std::string& value, const int slot = 0); - virtual std::string GetProperty(const int key, const std::string& default_ = "", const int slot = 0); - virtual void SetProperty(const int key, const int value, const int slot = 0); - virtual int GetProperty(const int key, const int default_ = 0, const int slot = 0); + + virtual void SetProperty(const int key, const std::string& value); + virtual std::string GetProperty(const int key, const std::string& default_ = ""); + virtual void SetProperty(const int key, const int value); + virtual int GetProperty(const int key, const int default_ = 0); protected: int fEventSize; int fEventRate; int fEventCounter; - virtual void Init(); + virtual void Run(); }; diff --git a/fairmq/prototest/FairMQProtoSink.cxx b/fairmq/prototest/FairMQProtoSink.cxx index 25a203e3..29e03810 100644 --- a/fairmq/prototest/FairMQProtoSink.cxx +++ b/fairmq/prototest/FairMQProtoSink.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -26,15 +26,13 @@ FairMQProtoSink::FairMQProtoSink() void FairMQProtoSink::Run() { - LOG(INFO) << ">>>>>>> Run <<<<<<<"; + const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); - boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); - - while (fState == RUNNING) + while (CheckCurrentState(RUNNING)) { FairMQMessage* msg = fTransportFactory->CreateMessage(); - fPayloadInputs->at(0)->Receive(msg); + dataInChannel.Receive(msg); sampler::Payload p; @@ -47,9 +45,6 @@ void FairMQProtoSink::Run() delete msg; } - - rateLogger.interrupt(); - rateLogger.join(); } FairMQProtoSink::~FairMQProtoSink() diff --git a/fairmq/prototest/FairMQProtoSink.h b/fairmq/prototest/FairMQProtoSink.h index 8b767d31..99f01b82 100644 --- a/fairmq/prototest/FairMQProtoSink.h +++ b/fairmq/prototest/FairMQProtoSink.h @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** diff --git a/fairmq/prototest/payload.pb.cc b/fairmq/prototest/payload.pb.cc deleted file mode 100644 index 3e6f004d..00000000 --- a/fairmq/prototest/payload.pb.cc +++ /dev/null @@ -1,698 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: payload.proto - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "payload.pb.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace sampler { - -namespace { - -const ::google::protobuf::Descriptor* Content_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Content_reflection_ = NULL; -const ::google::protobuf::Descriptor* Payload_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Payload_reflection_ = NULL; - -} // namespace - - -void protobuf_AssignDesc_payload_2eproto() { - protobuf_AddDesc_payload_2eproto(); - const ::google::protobuf::FileDescriptor* file = - ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "payload.proto"); - GOOGLE_CHECK(file != NULL); - Content_descriptor_ = file->message_type(0); - static const int Content_offsets_[5] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, a_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, b_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, x_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, y_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, z_), - }; - Content_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - Content_descriptor_, - Content::default_instance_, - Content_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Content, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(Content)); - Payload_descriptor_ = file->message_type(1); - static const int Payload_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Payload, data_), - }; - Payload_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - Payload_descriptor_, - Payload::default_instance_, - Payload_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Payload, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Payload, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(Payload)); -} - -namespace { - -GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); -inline void protobuf_AssignDescriptorsOnce() { - ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_payload_2eproto); -} - -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Content_descriptor_, &Content::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Payload_descriptor_, &Payload::default_instance()); -} - -} // namespace - -void protobuf_ShutdownFile_payload_2eproto() { - delete Content::default_instance_; - delete Content_reflection_; - delete Payload::default_instance_; - delete Payload_reflection_; -} - -void protobuf_AddDesc_payload_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\rpayload.proto\022\007sampler\"@\n\007Content\022\t\n\001a" - "\030\001 \001(\001\022\t\n\001b\030\002 \001(\001\022\t\n\001x\030\003 \001(\005\022\t\n\001y\030\004 \001(\005\022" - "\t\n\001z\030\005 \001(\005\")\n\007Payload\022\036\n\004data\030\001 \003(\0132\020.sa" - "mpler.Content", 133); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "payload.proto", &protobuf_RegisterTypes); - Content::default_instance_ = new Content(); - Payload::default_instance_ = new Payload(); - Content::default_instance_->InitAsDefaultInstance(); - Payload::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_payload_2eproto); -} - -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_payload_2eproto { - StaticDescriptorInitializer_payload_2eproto() { - protobuf_AddDesc_payload_2eproto(); - } -} static_descriptor_initializer_payload_2eproto_; - -// =================================================================== - -#ifndef _MSC_VER -const int Content::kAFieldNumber; -const int Content::kBFieldNumber; -const int Content::kXFieldNumber; -const int Content::kYFieldNumber; -const int Content::kZFieldNumber; -#endif // !_MSC_VER - -Content::Content() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void Content::InitAsDefaultInstance() { -} - -Content::Content(const Content& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void Content::SharedCtor() { - _cached_size_ = 0; - a_ = 0; - b_ = 0; - x_ = 0; - y_ = 0; - z_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Content::~Content() { - SharedDtor(); -} - -void Content::SharedDtor() { - if (this != default_instance_) { - } -} - -void Content::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Content::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Content_descriptor_; -} - -const Content& Content::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_payload_2eproto(); - return *default_instance_; -} - -Content* Content::default_instance_ = NULL; - -Content* Content::New() const { - return new Content; -} - -void Content::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - a_ = 0; - b_ = 0; - x_ = 0; - y_ = 0; - z_ = 0; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool Content::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional double a = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( - input, &a_))); - set_has_a(); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(17)) goto parse_b; - break; - } - - // optional double b = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_b: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( - input, &b_))); - set_has_b(); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(24)) goto parse_x; - break; - } - - // optional int32 x = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_x: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &x_))); - set_has_x(); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(32)) goto parse_y; - break; - } - - // optional int32 y = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_y: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &y_))); - set_has_y(); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(40)) goto parse_z; - break; - } - - // optional int32 z = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_z: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &z_))); - set_has_z(); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void Content::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional double a = 1; - if (has_a()) { - ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->a(), output); - } - - // optional double b = 2; - if (has_b()) { - ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->b(), output); - } - - // optional int32 x = 3; - if (has_x()) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->x(), output); - } - - // optional int32 y = 4; - if (has_y()) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->y(), output); - } - - // optional int32 z = 5; - if (has_z()) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->z(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* Content::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional double a = 1; - if (has_a()) { - target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->a(), target); - } - - // optional double b = 2; - if (has_b()) { - target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->b(), target); - } - - // optional int32 x = 3; - if (has_x()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->x(), target); - } - - // optional int32 y = 4; - if (has_y()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->y(), target); - } - - // optional int32 z = 5; - if (has_z()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->z(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int Content::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional double a = 1; - if (has_a()) { - total_size += 1 + 8; - } - - // optional double b = 2; - if (has_b()) { - total_size += 1 + 8; - } - - // optional int32 x = 3; - if (has_x()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->x()); - } - - // optional int32 y = 4; - if (has_y()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->y()); - } - - // optional int32 z = 5; - if (has_z()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->z()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Content::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const Content* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void Content::MergeFrom(const Content& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_a()) { - set_a(from.a()); - } - if (from.has_b()) { - set_b(from.b()); - } - if (from.has_x()) { - set_x(from.x()); - } - if (from.has_y()) { - set_y(from.y()); - } - if (from.has_z()) { - set_z(from.z()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void Content::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Content::CopyFrom(const Content& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Content::IsInitialized() const { - - return true; -} - -void Content::Swap(Content* other) { - if (other != this) { - std::swap(a_, other->a_); - std::swap(b_, other->b_); - std::swap(x_, other->x_); - std::swap(y_, other->y_); - std::swap(z_, other->z_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata Content::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Content_descriptor_; - metadata.reflection = Content_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int Payload::kDataFieldNumber; -#endif // !_MSC_VER - -Payload::Payload() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void Payload::InitAsDefaultInstance() { -} - -Payload::Payload(const Payload& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void Payload::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Payload::~Payload() { - SharedDtor(); -} - -void Payload::SharedDtor() { - if (this != default_instance_) { - } -} - -void Payload::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Payload::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Payload_descriptor_; -} - -const Payload& Payload::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_payload_2eproto(); - return *default_instance_; -} - -Payload* Payload::default_instance_ = NULL; - -Payload* Payload::New() const { - return new Payload; -} - -void Payload::Clear() { - data_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool Payload::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .sampler.Content data = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_data: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_data())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(10)) goto parse_data; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void Payload::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .sampler.Content data = 1; - for (int i = 0; i < this->data_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, this->data(i), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* Payload::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .sampler.Content data = 1; - for (int i = 0; i < this->data_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->data(i), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int Payload::ByteSize() const { - int total_size = 0; - - // repeated .sampler.Content data = 1; - total_size += 1 * this->data_size(); - for (int i = 0; i < this->data_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->data(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Payload::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const Payload* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void Payload::MergeFrom(const Payload& from) { - GOOGLE_CHECK_NE(&from, this); - data_.MergeFrom(from.data_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void Payload::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Payload::CopyFrom(const Payload& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Payload::IsInitialized() const { - - return true; -} - -void Payload::Swap(Payload* other) { - if (other != this) { - data_.Swap(&other->data_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata Payload::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Payload_descriptor_; - metadata.reflection = Payload_reflection_; - return metadata; -} - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace sampler - -// @@protoc_insertion_point(global_scope) diff --git a/fairmq/prototest/payload.pb.h b/fairmq/prototest/payload.pb.h deleted file mode 100644 index e39c9802..00000000 --- a/fairmq/prototest/payload.pb.h +++ /dev/null @@ -1,415 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: payload.proto - -#ifndef PROTOBUF_payload_2eproto__INCLUDED -#define PROTOBUF_payload_2eproto__INCLUDED - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 2005000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace sampler { - -// Internal implementation detail -- do not call these. -void protobuf_AddDesc_payload_2eproto(); -void protobuf_AssignDesc_payload_2eproto(); -void protobuf_ShutdownFile_payload_2eproto(); - -class Content; -class Payload; - -// =================================================================== - -class Content : public ::google::protobuf::Message { - public: - Content(); - virtual ~Content(); - - Content(const Content& from); - - inline Content& operator=(const Content& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Content& default_instance(); - - void Swap(Content* other); - - // implements Message ---------------------------------------------- - - Content* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Content& from); - void MergeFrom(const Content& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional double a = 1; - inline bool has_a() const; - inline void clear_a(); - static const int kAFieldNumber = 1; - inline double a() const; - inline void set_a(double value); - - // optional double b = 2; - inline bool has_b() const; - inline void clear_b(); - static const int kBFieldNumber = 2; - inline double b() const; - inline void set_b(double value); - - // optional int32 x = 3; - inline bool has_x() const; - inline void clear_x(); - static const int kXFieldNumber = 3; - inline ::google::protobuf::int32 x() const; - inline void set_x(::google::protobuf::int32 value); - - // optional int32 y = 4; - inline bool has_y() const; - inline void clear_y(); - static const int kYFieldNumber = 4; - inline ::google::protobuf::int32 y() const; - inline void set_y(::google::protobuf::int32 value); - - // optional int32 z = 5; - inline bool has_z() const; - inline void clear_z(); - static const int kZFieldNumber = 5; - inline ::google::protobuf::int32 z() const; - inline void set_z(::google::protobuf::int32 value); - - // @@protoc_insertion_point(class_scope:sampler.Content) - private: - inline void set_has_a(); - inline void clear_has_a(); - inline void set_has_b(); - inline void clear_has_b(); - inline void set_has_x(); - inline void clear_has_x(); - inline void set_has_y(); - inline void clear_has_y(); - inline void set_has_z(); - inline void clear_has_z(); - - ::google::protobuf::UnknownFieldSet _unknown_fields_; - - double a_; - double b_; - ::google::protobuf::int32 x_; - ::google::protobuf::int32 y_; - ::google::protobuf::int32 z_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; - - friend void protobuf_AddDesc_payload_2eproto(); - friend void protobuf_AssignDesc_payload_2eproto(); - friend void protobuf_ShutdownFile_payload_2eproto(); - - void InitAsDefaultInstance(); - static Content* default_instance_; -}; -// ------------------------------------------------------------------- - -class Payload : public ::google::protobuf::Message { - public: - Payload(); - virtual ~Payload(); - - Payload(const Payload& from); - - inline Payload& operator=(const Payload& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Payload& default_instance(); - - void Swap(Payload* other); - - // implements Message ---------------------------------------------- - - Payload* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Payload& from); - void MergeFrom(const Payload& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .sampler.Content data = 1; - inline int data_size() const; - inline void clear_data(); - static const int kDataFieldNumber = 1; - inline const ::sampler::Content& data(int index) const; - inline ::sampler::Content* mutable_data(int index); - inline ::sampler::Content* add_data(); - inline const ::google::protobuf::RepeatedPtrField< ::sampler::Content >& - data() const; - inline ::google::protobuf::RepeatedPtrField< ::sampler::Content >* - mutable_data(); - - // @@protoc_insertion_point(class_scope:sampler.Payload) - private: - - ::google::protobuf::UnknownFieldSet _unknown_fields_; - - ::google::protobuf::RepeatedPtrField< ::sampler::Content > data_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - friend void protobuf_AddDesc_payload_2eproto(); - friend void protobuf_AssignDesc_payload_2eproto(); - friend void protobuf_ShutdownFile_payload_2eproto(); - - void InitAsDefaultInstance(); - static Payload* default_instance_; -}; -// =================================================================== - - -// =================================================================== - -// Content - -// optional double a = 1; -inline bool Content::has_a() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void Content::set_has_a() { - _has_bits_[0] |= 0x00000001u; -} -inline void Content::clear_has_a() { - _has_bits_[0] &= ~0x00000001u; -} -inline void Content::clear_a() { - a_ = 0; - clear_has_a(); -} -inline double Content::a() const { - return a_; -} -inline void Content::set_a(double value) { - set_has_a(); - a_ = value; -} - -// optional double b = 2; -inline bool Content::has_b() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void Content::set_has_b() { - _has_bits_[0] |= 0x00000002u; -} -inline void Content::clear_has_b() { - _has_bits_[0] &= ~0x00000002u; -} -inline void Content::clear_b() { - b_ = 0; - clear_has_b(); -} -inline double Content::b() const { - return b_; -} -inline void Content::set_b(double value) { - set_has_b(); - b_ = value; -} - -// optional int32 x = 3; -inline bool Content::has_x() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void Content::set_has_x() { - _has_bits_[0] |= 0x00000004u; -} -inline void Content::clear_has_x() { - _has_bits_[0] &= ~0x00000004u; -} -inline void Content::clear_x() { - x_ = 0; - clear_has_x(); -} -inline ::google::protobuf::int32 Content::x() const { - return x_; -} -inline void Content::set_x(::google::protobuf::int32 value) { - set_has_x(); - x_ = value; -} - -// optional int32 y = 4; -inline bool Content::has_y() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void Content::set_has_y() { - _has_bits_[0] |= 0x00000008u; -} -inline void Content::clear_has_y() { - _has_bits_[0] &= ~0x00000008u; -} -inline void Content::clear_y() { - y_ = 0; - clear_has_y(); -} -inline ::google::protobuf::int32 Content::y() const { - return y_; -} -inline void Content::set_y(::google::protobuf::int32 value) { - set_has_y(); - y_ = value; -} - -// optional int32 z = 5; -inline bool Content::has_z() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void Content::set_has_z() { - _has_bits_[0] |= 0x00000010u; -} -inline void Content::clear_has_z() { - _has_bits_[0] &= ~0x00000010u; -} -inline void Content::clear_z() { - z_ = 0; - clear_has_z(); -} -inline ::google::protobuf::int32 Content::z() const { - return z_; -} -inline void Content::set_z(::google::protobuf::int32 value) { - set_has_z(); - z_ = value; -} - -// ------------------------------------------------------------------- - -// Payload - -// repeated .sampler.Content data = 1; -inline int Payload::data_size() const { - return data_.size(); -} -inline void Payload::clear_data() { - data_.Clear(); -} -inline const ::sampler::Content& Payload::data(int index) const { - return data_.Get(index); -} -inline ::sampler::Content* Payload::mutable_data(int index) { - return data_.Mutable(index); -} -inline ::sampler::Content* Payload::add_data() { - return data_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::sampler::Content >& -Payload::data() const { - return data_; -} -inline ::google::protobuf::RepeatedPtrField< ::sampler::Content >* -Payload::mutable_data() { - return &data_; -} - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace sampler - -#ifndef SWIG -namespace google { -namespace protobuf { - - -} // namespace google -} // namespace protobuf -#endif // SWIG - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_payload_2eproto__INCLUDED diff --git a/fairmq/run/runBinSampler.cxx b/fairmq/prototest/runBinSampler.cxx similarity index 73% rename from fairmq/run/runBinSampler.cxx rename to fairmq/prototest/runBinSampler.cxx index fe0ceaab..d65e02ce 100644 --- a/fairmq/run/runBinSampler.cxx +++ b/fairmq/prototest/runBinSampler.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,29 +27,6 @@ using namespace std; -FairMQBinSampler sampler; - -static void s_signal_handler(int signal) -{ - cout << endl << "Caught signal " << signal << endl; - - sampler.ChangeState(FairMQBinSampler::STOP); - sampler.ChangeState(FairMQBinSampler::END); - - cout << "Shutdown complete. Bye!" << endl; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -125,7 +101,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQBinSampler sampler; + sampler.CatchSignals(); DeviceOptions_t options; try @@ -151,36 +128,26 @@ int main(int argc, char** argv) sampler.SetTransport(transportFactory); + FairMQChannel outputChannel(options.outputSocketType, options.outputMethod, options.outputAddress); + outputChannel.UpdateSndBufSize(options.outputBufSize); + outputChannel.UpdateRcvBufSize(options.outputBufSize); + outputChannel.UpdateRateLogging(1); + + sampler.fChannels["data-out"].push_back(outputChannel); + sampler.SetProperty(FairMQBinSampler::Id, options.id); sampler.SetProperty(FairMQBinSampler::EventSize, options.eventSize); sampler.SetProperty(FairMQBinSampler::EventRate, options.eventRate); sampler.SetProperty(FairMQBinSampler::NumIoThreads, options.ioThreads); - sampler.SetProperty(FairMQBinSampler::NumInputs, 0); - sampler.SetProperty(FairMQBinSampler::NumOutputs, 1); + sampler.ChangeState("INIT_DEVICE"); + sampler.WaitForEndOfState("INIT_DEVICE"); - sampler.ChangeState(FairMQBinSampler::INIT); + sampler.ChangeState("INIT_TASK"); + sampler.WaitForEndOfState("INIT_TASK"); - sampler.SetProperty(FairMQBinSampler::OutputSocketType, options.outputSocketType); - sampler.SetProperty(FairMQBinSampler::OutputSndBufSize, options.outputBufSize); - sampler.SetProperty(FairMQBinSampler::OutputMethod, options.outputMethod); - sampler.SetProperty(FairMQBinSampler::OutputAddress, options.outputAddress); - - sampler.ChangeState(FairMQBinSampler::SETOUTPUT); - sampler.ChangeState(FairMQBinSampler::SETINPUT); - sampler.ChangeState(FairMQBinSampler::BIND); - sampler.ChangeState(FairMQBinSampler::CONNECT); - sampler.ChangeState(FairMQBinSampler::RUN); - - // wait until the running thread has finished processing. - boost::unique_lock lock(sampler.fRunningMutex); - while (!sampler.fRunningFinished) - { - sampler.fRunningCondition.wait(lock); - } - - sampler.ChangeState(FairMQBinSampler::STOP); - sampler.ChangeState(FairMQBinSampler::END); + sampler.ChangeState("RUN"); + sampler.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runBinSink.cxx b/fairmq/prototest/runBinSink.cxx similarity index 69% rename from fairmq/run/runBinSink.cxx rename to fairmq/prototest/runBinSink.cxx index 9b3fbe21..5ae89062 100644 --- a/fairmq/run/runBinSink.cxx +++ b/fairmq/prototest/runBinSink.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,29 +27,6 @@ using namespace std; -FairMQBinSink sink; - -static void s_signal_handler(int signal) -{ - cout << endl << "Caught signal " << signal << endl; - - sink.ChangeState(FairMQBinSink::STOP); - sink.ChangeState(FairMQBinSink::END); - - cout << "Shutdown complete. Bye!" << endl; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -115,7 +91,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQBinSink sink; + sink.CatchSignals(); DeviceOptions_t options; try @@ -139,34 +116,24 @@ int main(int argc, char** argv) sink.SetTransport(transportFactory); + FairMQChannel inputChannel(options.inputSocketType, options.inputMethod, options.inputAddress); + inputChannel.UpdateSndBufSize(options.inputBufSize); + inputChannel.UpdateRcvBufSize(options.inputBufSize); + inputChannel.UpdateRateLogging(1); + + sink.fChannels["data-in"].push_back(inputChannel); + sink.SetProperty(FairMQBinSink::Id, options.id); sink.SetProperty(FairMQBinSink::NumIoThreads, options.ioThreads); - sink.SetProperty(FairMQBinSink::NumInputs, 1); - sink.SetProperty(FairMQBinSink::NumOutputs, 0); + sink.ChangeState("INIT_DEVICE"); + sink.WaitForEndOfState("INIT_DEVICE"); - sink.ChangeState(FairMQBinSink::INIT); + sink.ChangeState("INIT_TASK"); + sink.WaitForEndOfState("INIT_TASK"); - sink.SetProperty(FairMQBinSink::InputSocketType, options.inputSocketType); - sink.SetProperty(FairMQBinSink::InputRcvBufSize, options.inputBufSize); - sink.SetProperty(FairMQBinSink::InputMethod, options.inputMethod); - sink.SetProperty(FairMQBinSink::InputAddress, options.inputAddress); - - sink.ChangeState(FairMQBinSink::SETOUTPUT); - sink.ChangeState(FairMQBinSink::SETINPUT); - sink.ChangeState(FairMQBinSink::BIND); - sink.ChangeState(FairMQBinSink::CONNECT); - sink.ChangeState(FairMQBinSink::RUN); - - // wait until the running thread has finished processing. - boost::unique_lock lock(sink.fRunningMutex); - while (!sink.fRunningFinished) - { - sink.fRunningCondition.wait(lock); - } - - sink.ChangeState(FairMQBinSink::STOP); - sink.ChangeState(FairMQBinSink::END); + sink.ChangeState("RUN"); + sink.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runProtoSampler.cxx b/fairmq/prototest/runProtoSampler.cxx similarity index 72% rename from fairmq/run/runProtoSampler.cxx rename to fairmq/prototest/runProtoSampler.cxx index 91d314cd..a5b3082d 100644 --- a/fairmq/run/runProtoSampler.cxx +++ b/fairmq/prototest/runProtoSampler.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,29 +27,6 @@ using namespace std; -FairMQProtoSampler sampler; - -static void s_signal_handler(int signal) -{ - cout << endl << "Caught signal " << signal << endl; - - sampler.ChangeState(FairMQProtoSampler::STOP); - sampler.ChangeState(FairMQProtoSampler::END); - - cout << "Shutdown complete. Bye!" << endl; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -125,7 +101,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQProtoSampler sampler; + sampler.CatchSignals(); DeviceOptions_t options; try @@ -151,36 +128,26 @@ int main(int argc, char** argv) sampler.SetTransport(transportFactory); + FairMQChannel outputChannel(options.outputSocketType, options.outputMethod, options.outputAddress); + outputChannel.UpdateSndBufSize(options.outputBufSize); + outputChannel.UpdateRcvBufSize(options.outputBufSize); + outputChannel.UpdateRateLogging(1); + + sampler.fChannels["data-out"].push_back(outputChannel); + sampler.SetProperty(FairMQProtoSampler::Id, options.id); sampler.SetProperty(FairMQProtoSampler::EventSize, options.eventSize); sampler.SetProperty(FairMQProtoSampler::EventRate, options.eventRate); sampler.SetProperty(FairMQProtoSampler::NumIoThreads, options.ioThreads); - sampler.SetProperty(FairMQProtoSampler::NumInputs, 0); - sampler.SetProperty(FairMQProtoSampler::NumOutputs, 1); + sampler.ChangeState("INIT_DEVICE"); + sampler.WaitForEndOfState("INIT_DEVICE"); - sampler.ChangeState(FairMQProtoSampler::INIT); + sampler.ChangeState("INIT_TASK"); + sampler.WaitForEndOfState("INIT_TASK"); - sampler.SetProperty(FairMQProtoSampler::OutputSocketType, options.outputSocketType); - sampler.SetProperty(FairMQProtoSampler::OutputSndBufSize, options.outputBufSize); - sampler.SetProperty(FairMQProtoSampler::OutputMethod, options.outputMethod); - sampler.SetProperty(FairMQProtoSampler::OutputAddress, options.outputAddress); - - sampler.ChangeState(FairMQProtoSampler::SETOUTPUT); - sampler.ChangeState(FairMQProtoSampler::SETINPUT); - sampler.ChangeState(FairMQProtoSampler::BIND); - sampler.ChangeState(FairMQProtoSampler::CONNECT); - sampler.ChangeState(FairMQProtoSampler::RUN); - - // wait until the running thread has finished processing. - boost::unique_lock lock(sampler.fRunningMutex); - while (!sampler.fRunningFinished) - { - sampler.fRunningCondition.wait(lock); - } - - sampler.ChangeState(FairMQProtoSampler::STOP); - sampler.ChangeState(FairMQProtoSampler::END); + sampler.ChangeState("RUN"); + sampler.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runProtoSink.cxx b/fairmq/prototest/runProtoSink.cxx similarity index 69% rename from fairmq/run/runProtoSink.cxx rename to fairmq/prototest/runProtoSink.cxx index 9d3ab62f..96e84139 100644 --- a/fairmq/run/runProtoSink.cxx +++ b/fairmq/prototest/runProtoSink.cxx @@ -1,8 +1,8 @@ /******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,29 +27,6 @@ using namespace std; -FairMQProtoSink sink; - -static void s_signal_handler(int signal) -{ - cout << endl << "Caught signal " << signal << endl; - - sink.ChangeState(FairMQProtoSink::STOP); - sink.ChangeState(FairMQProtoSink::END); - - cout << "Shutdown complete. Bye!" << endl; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -115,7 +91,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQProtoSink sink; + sink.CatchSignals(); DeviceOptions_t options; try @@ -139,34 +116,24 @@ int main(int argc, char** argv) sink.SetTransport(transportFactory); + FairMQChannel inputChannel(options.inputSocketType, options.inputMethod, options.inputAddress); + inputChannel.UpdateSndBufSize(options.inputBufSize); + inputChannel.UpdateRcvBufSize(options.inputBufSize); + inputChannel.UpdateRateLogging(1); + + sink.fChannels["data-in"].push_back(inputChannel); + sink.SetProperty(FairMQProtoSink::Id, options.id); sink.SetProperty(FairMQProtoSink::NumIoThreads, options.ioThreads); - sink.SetProperty(FairMQProtoSink::NumInputs, 1); - sink.SetProperty(FairMQProtoSink::NumOutputs, 0); + sink.ChangeState("INIT_DEVICE"); + sink.WaitForEndOfState("INIT_DEVICE"); - sink.ChangeState(FairMQProtoSink::INIT); + sink.ChangeState("INIT_TASK"); + sink.WaitForEndOfState("INIT_TASK"); - sink.SetProperty(FairMQProtoSink::InputSocketType, options.inputSocketType); - sink.SetProperty(FairMQProtoSink::InputRcvBufSize, options.inputBufSize); - sink.SetProperty(FairMQProtoSink::InputMethod, options.inputMethod); - sink.SetProperty(FairMQProtoSink::InputAddress, options.inputAddress); - - sink.ChangeState(FairMQProtoSink::SETOUTPUT); - sink.ChangeState(FairMQProtoSink::SETINPUT); - sink.ChangeState(FairMQProtoSink::BIND); - sink.ChangeState(FairMQProtoSink::CONNECT); - sink.ChangeState(FairMQProtoSink::RUN); - - // wait until the running thread has finished processing. - boost::unique_lock lock(sink.fRunningMutex); - while (!sink.fRunningFinished) - { - sink.fRunningCondition.wait(lock); - } - - sink.ChangeState(FairMQProtoSink::STOP); - sink.ChangeState(FairMQProtoSink::END); + sink.ChangeState("RUN"); + sink.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runBenchmarkSampler.cxx b/fairmq/run/runBenchmarkSampler.cxx index 59022ec2..536c01ab 100644 --- a/fairmq/run/runBenchmarkSampler.cxx +++ b/fairmq/run/runBenchmarkSampler.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -32,31 +31,10 @@ using namespace std; using namespace FairMQParser; using namespace boost::program_options; -FairMQBenchmarkSampler sampler; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sampler.ChangeState(FairMQBenchmarkSampler::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQBenchmarkSampler sampler; + sampler.CatchSignals(); FairMQProgOptions config; @@ -79,7 +57,7 @@ int main(int argc, char** argv) return 0; } - string filename = config.GetValue("config-json-filename"); + string filename = config.GetValue("config-json-file"); string id = config.GetValue("id"); config.UserParser(filename, id); @@ -101,25 +79,14 @@ int main(int argc, char** argv) sampler.SetProperty(FairMQBenchmarkSampler::EventRate, eventRate); sampler.SetProperty(FairMQBenchmarkSampler::NumIoThreads, ioThreads); - sampler.ChangeState(FairMQBenchmarkSampler::INIT_DEVICE); - sampler.WaitForEndOfState(FairMQBenchmarkSampler::INIT_DEVICE); + sampler.ChangeState("INIT_DEVICE"); + sampler.WaitForEndOfState("INIT_DEVICE"); - sampler.ChangeState(FairMQBenchmarkSampler::INIT_TASK); - sampler.WaitForEndOfState(FairMQBenchmarkSampler::INIT_TASK); - - sampler.ChangeState(FairMQBenchmarkSampler::RUN); - sampler.WaitForEndOfState(FairMQBenchmarkSampler::RUN); - - sampler.ChangeState(FairMQBenchmarkSampler::STOP); - - sampler.ChangeState(FairMQBenchmarkSampler::RESET_TASK); - sampler.WaitForEndOfState(FairMQBenchmarkSampler::RESET_TASK); - - sampler.ChangeState(FairMQBenchmarkSampler::RESET_DEVICE); - sampler.WaitForEndOfState(FairMQBenchmarkSampler::RESET_DEVICE); - - sampler.ChangeState(FairMQBenchmarkSampler::END); + sampler.ChangeState("INIT_TASK"); + sampler.WaitForEndOfState("INIT_TASK"); + sampler.ChangeState("RUN"); + sampler.InteractiveStateLoop(); } catch (exception& e) { diff --git a/fairmq/run/runBuffer.cxx b/fairmq/run/runBuffer.cxx index bb828a8f..3dd7693e 100644 --- a/fairmq/run/runBuffer.cxx +++ b/fairmq/run/runBuffer.cxx @@ -9,11 +9,10 @@ * runBuffer.cxx * * @since 2012-10-26 - * @author: D. Klein, A. Rybalchenko + * @author D. Klein, A. Rybalchenko */ #include -#include #include "boost/program_options.hpp" @@ -28,28 +27,6 @@ using namespace std; -FairMQBuffer buffer; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - buffer.ChangeState(FairMQBuffer::END); - - LOG(INFO) << "Shutdown complete"; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -135,7 +112,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQBuffer buffer; + buffer.CatchSignals(); DeviceOptions_t options; try @@ -176,24 +154,14 @@ int main(int argc, char** argv) buffer.SetProperty(FairMQBuffer::Id, options.id); buffer.SetProperty(FairMQBuffer::NumIoThreads, options.ioThreads); - buffer.ChangeState(FairMQBuffer::INIT_DEVICE); - buffer.WaitForEndOfState(FairMQBuffer::INIT_DEVICE); + buffer.ChangeState("INIT_DEVICE"); + buffer.WaitForEndOfState("INIT_DEVICE"); - buffer.ChangeState(FairMQBuffer::INIT_TASK); - buffer.WaitForEndOfState(FairMQBuffer::INIT_TASK); + buffer.ChangeState("INIT_TASK"); + buffer.WaitForEndOfState("INIT_TASK"); - buffer.ChangeState(FairMQBuffer::RUN); - buffer.WaitForEndOfState(FairMQBuffer::RUN); - - buffer.ChangeState(FairMQBuffer::STOP); - - buffer.ChangeState(FairMQBuffer::RESET_TASK); - buffer.WaitForEndOfState(FairMQBuffer::RESET_TASK); - - buffer.ChangeState(FairMQBuffer::RESET_DEVICE); - buffer.WaitForEndOfState(FairMQBuffer::RESET_DEVICE); - - buffer.ChangeState(FairMQBuffer::END); + buffer.ChangeState("RUN"); + buffer.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runMerger.cxx b/fairmq/run/runMerger.cxx index ffa2cc7e..e470c97e 100644 --- a/fairmq/run/runMerger.cxx +++ b/fairmq/run/runMerger.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,28 +27,6 @@ using namespace std; -FairMQMerger merger; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - merger.ChangeState(FairMQMerger::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -94,7 +71,7 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) bpo::variables_map vm; bpo::store(bpo::parse_command_line(_argc, _argv, desc), vm); - if ( vm.count("help") ) + if (vm.count("help")) { LOG(INFO) << "FairMQ Merger" << endl << desc; return false; @@ -102,37 +79,37 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) bpo::notify(vm); - if ( vm.count("id") ) + if (vm.count("id")) _options->id = vm["id"].as(); - if ( vm.count("io-threads") ) + if (vm.count("io-threads")) _options->ioThreads = vm["io-threads"].as(); - if ( vm.count("num-inputs") ) + if (vm.count("num-inputs")) _options->numInputs = vm["num-inputs"].as(); - if ( vm.count("input-socket-type") ) + if (vm.count("input-socket-type")) _options->inputSocketType = vm["input-socket-type"].as< vector >(); - if ( vm.count("input-buff-size") ) + if (vm.count("input-buff-size")) _options->inputBufSize = vm["input-buff-size"].as< vector >(); - if ( vm.count("input-method") ) + if (vm.count("input-method")) _options->inputMethod = vm["input-method"].as< vector >(); - if ( vm.count("input-address") ) + if (vm.count("input-address")) _options->inputAddress = vm["input-address"].as< vector >(); - if ( vm.count("output-socket-type") ) + if (vm.count("output-socket-type")) _options->outputSocketType = vm["output-socket-type"].as(); - if ( vm.count("output-buff-size") ) + if (vm.count("output-buff-size")) _options->outputBufSize = vm["output-buff-size"].as(); - if ( vm.count("output-method") ) + if (vm.count("output-method")) _options->outputMethod = vm["output-method"].as(); - if ( vm.count("output-address") ) + if (vm.count("output-address")) _options->outputAddress = vm["output-address"].as(); return true; @@ -140,7 +117,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQMerger merger; + merger.CatchSignals(); DeviceOptions_t options; try @@ -184,24 +162,14 @@ int main(int argc, char** argv) merger.SetProperty(FairMQMerger::Id, options.id); merger.SetProperty(FairMQMerger::NumIoThreads, options.ioThreads); - merger.ChangeState(FairMQMerger::INIT_DEVICE); - merger.WaitForEndOfState(FairMQMerger::INIT_DEVICE); + merger.ChangeState("INIT_DEVICE"); + merger.WaitForEndOfState("INIT_DEVICE"); - merger.ChangeState(FairMQMerger::INIT_TASK); - merger.WaitForEndOfState(FairMQMerger::INIT_TASK); + merger.ChangeState("INIT_TASK"); + merger.WaitForEndOfState("INIT_TASK"); - merger.ChangeState(FairMQMerger::RUN); - merger.WaitForEndOfState(FairMQMerger::RUN); - - merger.ChangeState(FairMQMerger::STOP); - - merger.ChangeState(FairMQMerger::RESET_TASK); - merger.WaitForEndOfState(FairMQMerger::RESET_TASK); - - merger.ChangeState(FairMQMerger::RESET_DEVICE); - merger.WaitForEndOfState(FairMQMerger::RESET_DEVICE); - - merger.ChangeState(FairMQMerger::END); + merger.ChangeState("RUN"); + merger.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runProxy.cxx b/fairmq/run/runProxy.cxx index 16a73e92..f5e289cc 100644 --- a/fairmq/run/runProxy.cxx +++ b/fairmq/run/runProxy.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,28 +27,6 @@ using namespace std; -FairMQProxy proxy; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - proxy.ChangeState(FairMQProxy::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -135,7 +112,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQProxy proxy; + proxy.CatchSignals(); DeviceOptions_t options; try @@ -176,24 +154,14 @@ int main(int argc, char** argv) proxy.SetProperty(FairMQProxy::Id, options.id); proxy.SetProperty(FairMQProxy::NumIoThreads, options.ioThreads); - proxy.ChangeState(FairMQProxy::INIT_DEVICE); - proxy.WaitForEndOfState(FairMQProxy::INIT_DEVICE); + proxy.ChangeState("INIT_DEVICE"); + proxy.WaitForEndOfState("INIT_DEVICE"); - proxy.ChangeState(FairMQProxy::INIT_TASK); - proxy.WaitForEndOfState(FairMQProxy::INIT_TASK); + proxy.ChangeState("INIT_TASK"); + proxy.WaitForEndOfState("INIT_TASK"); - proxy.ChangeState(FairMQProxy::RUN); - proxy.WaitForEndOfState(FairMQProxy::RUN); - - proxy.ChangeState(FairMQProxy::STOP); - - proxy.ChangeState(FairMQProxy::RESET_TASK); - proxy.WaitForEndOfState(FairMQProxy::RESET_TASK); - - proxy.ChangeState(FairMQProxy::RESET_DEVICE); - proxy.WaitForEndOfState(FairMQProxy::RESET_DEVICE); - - proxy.ChangeState(FairMQProxy::END); + proxy.ChangeState("RUN"); + proxy.InteractiveStateLoop(); return 0; } diff --git a/fairmq/run/runSink.cxx b/fairmq/run/runSink.cxx index 587a0035..333072fe 100644 --- a/fairmq/run/runSink.cxx +++ b/fairmq/run/runSink.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -32,31 +31,10 @@ using namespace std; using namespace FairMQParser; using namespace boost::program_options; -FairMQSink sink; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - sink.ChangeState(FairMQSink::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - int main(int argc, char** argv) { - s_catch_signals(); + FairMQSink sink; + sink.CatchSignals(); FairMQProgOptions config; @@ -75,7 +53,7 @@ int main(int argc, char** argv) return 0; } - string filename = config.GetValue("config-json-filename"); + string filename = config.GetValue("config-json-file"); string id = config.GetValue("id"); config.UserParser(filename, id); @@ -95,25 +73,14 @@ int main(int argc, char** argv) sink.SetProperty(FairMQSink::Id, id); sink.SetProperty(FairMQSink::NumIoThreads, ioThreads); - sink.ChangeState(FairMQSink::INIT_DEVICE); - sink.WaitForEndOfState(FairMQSink::INIT_DEVICE); + sink.ChangeState("INIT_DEVICE"); + sink.WaitForEndOfState("INIT_DEVICE"); - sink.ChangeState(FairMQSink::INIT_TASK); - sink.WaitForEndOfState(FairMQSink::INIT_TASK); - - sink.ChangeState(FairMQSink::RUN); - sink.WaitForEndOfState(FairMQSink::RUN); - - sink.ChangeState(FairMQSink::STOP); - - sink.ChangeState(FairMQSink::RESET_TASK); - sink.WaitForEndOfState(FairMQSink::RESET_TASK); - - sink.ChangeState(FairMQSink::RESET_DEVICE); - sink.WaitForEndOfState(FairMQSink::RESET_DEVICE); - - sink.ChangeState(FairMQSink::END); + sink.ChangeState("INIT_TASK"); + sink.WaitForEndOfState("INIT_TASK"); + sink.ChangeState("RUN"); + sink.InteractiveStateLoop(); } catch (exception& e) { diff --git a/fairmq/run/runSplitter.cxx b/fairmq/run/runSplitter.cxx index 57395bb8..ecd316bb 100644 --- a/fairmq/run/runSplitter.cxx +++ b/fairmq/run/runSplitter.cxx @@ -13,7 +13,6 @@ */ #include -#include #include "boost/program_options.hpp" @@ -28,28 +27,6 @@ using namespace std; -FairMQSplitter splitter; - -static void s_signal_handler(int signal) -{ - LOG(INFO) << "Caught signal " << signal; - - splitter.ChangeState(FairMQSplitter::END); - - LOG(INFO) << "Shutdown complete."; - exit(1); -} - -static void s_catch_signals(void) -{ - struct sigaction action; - action.sa_handler = s_signal_handler; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); -} - typedef struct DeviceOptions { DeviceOptions() : @@ -141,7 +118,8 @@ inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options) int main(int argc, char** argv) { - s_catch_signals(); + FairMQSplitter splitter; + splitter.CatchSignals(); DeviceOptions_t options; try @@ -185,24 +163,14 @@ int main(int argc, char** argv) splitter.SetProperty(FairMQSplitter::Id, options.id); splitter.SetProperty(FairMQSplitter::NumIoThreads, options.ioThreads); - splitter.ChangeState(FairMQSplitter::INIT_DEVICE); - splitter.WaitForEndOfState(FairMQSplitter::INIT_DEVICE); + splitter.ChangeState("INIT_DEVICE"); + splitter.WaitForEndOfState("INIT_DEVICE"); - splitter.ChangeState(FairMQSplitter::INIT_TASK); - splitter.WaitForEndOfState(FairMQSplitter::INIT_TASK); + splitter.ChangeState("INIT_TASK"); + splitter.WaitForEndOfState("INIT_TASK"); - splitter.ChangeState(FairMQSplitter::RUN); - splitter.WaitForEndOfState(FairMQSplitter::RUN); - - splitter.ChangeState(FairMQSplitter::STOP); - - splitter.ChangeState(FairMQSplitter::RESET_TASK); - splitter.WaitForEndOfState(FairMQSplitter::RESET_TASK); - - splitter.ChangeState(FairMQSplitter::RESET_DEVICE); - splitter.WaitForEndOfState(FairMQSplitter::RESET_DEVICE); - - splitter.ChangeState(FairMQSplitter::END); + splitter.ChangeState("RUN"); + splitter.InteractiveStateLoop(); return 0; } diff --git a/fairmq/zeromq/FairMQPollerZMQ.cxx b/fairmq/zeromq/FairMQPollerZMQ.cxx index 8f979c71..5a2f9778 100644 --- a/fairmq/zeromq/FairMQPollerZMQ.cxx +++ b/fairmq/zeromq/FairMQPollerZMQ.cxx @@ -21,7 +21,8 @@ using namespace std; FairMQPollerZMQ::FairMQPollerZMQ(const vector& channels) : items() - , fNumItems() + , fNumItems(0) + , fOffsetMap() { fNumItems = channels.size(); items = new zmq_pollitem_t[fNumItems]; @@ -35,15 +36,101 @@ FairMQPollerZMQ::FairMQPollerZMQ(const vector& channels) } } -void FairMQPollerZMQ::Poll(int timeout) +FairMQPollerZMQ::FairMQPollerZMQ(map< string,vector >& channelsMap, initializer_list channelList) + : items() + , fNumItems(0) + , fOffsetMap() { - if (zmq_poll(items, fNumItems, timeout) < 0) + int offset = 0; + + try { - LOG(ERROR) << "polling failed, reason: " << zmq_strerror(errno); + // calculate offsets and the total size of the poll item set + for (string channel : channelList) + { + fOffsetMap[channel] = offset; + offset += channelsMap.at(channel).size(); + fNumItems += channelsMap.at(channel).size(); + } + + items = new zmq_pollitem_t[fNumItems]; + + int index = 0; + for (string channel : channelList) + { + for (int i = 0; i < channelsMap.at(channel).size(); ++i) + { + index = fOffsetMap[channel] + i; + items[index].socket = channelsMap.at(channel).at(i).fSocket->GetSocket(); + items[index].fd = 0; + items[index].events = ZMQ_POLLIN; + items[index].revents = 0; + } + } + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "At least one of the provided channel keys for poller initialization is invalid"; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); } } -bool FairMQPollerZMQ::CheckInput(int index) +FairMQPollerZMQ::FairMQPollerZMQ(FairMQSocket& dataSocket, FairMQSocket& cmdSocket) + : items() + , fNumItems(2) + , fOffsetMap() +{ + items = new zmq_pollitem_t[fNumItems]; + + items[0].socket = cmdSocket.GetSocket(); + items[0].fd = 0; + items[0].events = ZMQ_POLLIN; + items[0].revents = 0; + + items[1].socket = dataSocket.GetSocket(); + items[1].fd = 0; + items[1].revents = 0; + + int type = 0; + size_t size = sizeof(type); + zmq_getsockopt (dataSocket.GetSocket(), ZMQ_TYPE, &type, &size); + + if (type == ZMQ_REQ || type == ZMQ_REP || type == ZMQ_PAIR || type == ZMQ_DEALER || type == ZMQ_ROUTER) + { + items[1].events = ZMQ_POLLIN|ZMQ_POLLOUT; + } + else if (type == ZMQ_PUSH || type == ZMQ_PUB || type == ZMQ_XPUB) + { + items[1].events = ZMQ_POLLOUT; + } + else if (type == ZMQ_PULL || type == ZMQ_SUB || type == ZMQ_XSUB) + { + items[1].events = ZMQ_POLLIN; + } + else + { + LOG(ERROR) << "invalid poller configuration, exiting."; + exit(EXIT_FAILURE); + } +} + +void FairMQPollerZMQ::Poll(const int timeout) +{ + if (zmq_poll(items, fNumItems, timeout) < 0) + { + if (errno == ETERM) + { + LOG(DEBUG) << "polling exited, reason: " << zmq_strerror(errno); + } + else + { + LOG(ERROR) << "polling failed, reason: " << zmq_strerror(errno); + } + } +} + +bool FairMQPollerZMQ::CheckInput(const int index) { if (items[index].revents & ZMQ_POLLIN) { @@ -53,7 +140,7 @@ bool FairMQPollerZMQ::CheckInput(int index) return false; } -bool FairMQPollerZMQ::CheckOutput(int index) +bool FairMQPollerZMQ::CheckOutput(const int index) { if (items[index].revents & ZMQ_POLLOUT) { @@ -63,6 +150,44 @@ bool FairMQPollerZMQ::CheckOutput(int index) return false; } +bool FairMQPollerZMQ::CheckInput(const string channelKey, const int index) +{ + try + { + if (items[fOffsetMap.at(channelKey) + index].revents & ZMQ_POLLIN) + { + return true; + } + + return false; + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\""; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); + } +} + +bool FairMQPollerZMQ::CheckOutput(const string channelKey, const int index) +{ + try + { + if (items[fOffsetMap.at(channelKey) + index].revents & ZMQ_POLLOUT) + { + return true; + } + + return false; + } + catch (const std::out_of_range& oor) + { + LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\""; + LOG(ERROR) << "Out of Range error: " << oor.what() << '\n'; + exit(EXIT_FAILURE); + } +} + FairMQPollerZMQ::~FairMQPollerZMQ() { if (items != NULL) diff --git a/fairmq/zeromq/FairMQPollerZMQ.h b/fairmq/zeromq/FairMQPollerZMQ.h index 9c21beee..585c9efe 100644 --- a/fairmq/zeromq/FairMQPollerZMQ.h +++ b/fairmq/zeromq/FairMQPollerZMQ.h @@ -16,25 +16,40 @@ #define FAIRMQPOLLERZMQ_H_ #include +#include +#include #include "FairMQPoller.h" #include "FairMQChannel.h" +#include "FairMQTransportFactoryZMQ.h" + +class FairMQChannel; class FairMQPollerZMQ : public FairMQPoller { + friend class FairMQChannel; + friend class FairMQTransportFactoryZMQ; + public: FairMQPollerZMQ(const std::vector& channels); + FairMQPollerZMQ(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList); - virtual void Poll(int timeout); - virtual bool CheckInput(int index); - virtual bool CheckOutput(int index); + virtual void Poll(const int timeout); + virtual bool CheckInput(const int index); + virtual bool CheckOutput(const int index); + virtual bool CheckInput(const std::string channelKey, const int index); + virtual bool CheckOutput(const std::string channelKey, const int index); virtual ~FairMQPollerZMQ(); private: + FairMQPollerZMQ(FairMQSocket& dataSocket, FairMQSocket& cmdSocket); + zmq_pollitem_t* items; int fNumItems; + std::unordered_map fOffsetMap; + /// Copy Constructor FairMQPollerZMQ(const FairMQPollerZMQ&); FairMQPollerZMQ operator=(const FairMQPollerZMQ&); diff --git a/fairmq/zeromq/FairMQSocketZMQ.cxx b/fairmq/zeromq/FairMQSocketZMQ.cxx index 1a588590..1ca8c4aa 100644 --- a/fairmq/zeromq/FairMQSocketZMQ.cxx +++ b/fairmq/zeromq/FairMQSocketZMQ.cxx @@ -98,6 +98,8 @@ void FairMQSocketZMQ::Connect(const string& address) if (zmq_connect(fSocket, address.c_str()) != 0) { LOG(ERROR) << "failed connecting socket " << fId << ", reason: " << zmq_strerror(errno); + // error here means incorrect configuration. exit if it happens. + exit(EXIT_FAILURE); } } diff --git a/fairmq/zeromq/FairMQTransportFactoryZMQ.cxx b/fairmq/zeromq/FairMQTransportFactoryZMQ.cxx index 9b01dcdd..0fc08b3b 100644 --- a/fairmq/zeromq/FairMQTransportFactoryZMQ.cxx +++ b/fairmq/zeromq/FairMQTransportFactoryZMQ.cxx @@ -49,3 +49,13 @@ FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const vector >& channelsMap, std::initializer_list channelList) +{ + return new FairMQPollerZMQ(channelsMap, channelList); +} + +FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(FairMQSocket& dataSocket, FairMQSocket& cmdSocket) +{ + return new FairMQPollerZMQ(dataSocket, cmdSocket); +} diff --git a/fairmq/zeromq/FairMQTransportFactoryZMQ.h b/fairmq/zeromq/FairMQTransportFactoryZMQ.h index ca9205b8..9ee4e8db 100644 --- a/fairmq/zeromq/FairMQTransportFactoryZMQ.h +++ b/fairmq/zeromq/FairMQTransportFactoryZMQ.h @@ -31,8 +31,12 @@ class FairMQTransportFactoryZMQ : public FairMQTransportFactory virtual FairMQMessage* CreateMessage(); virtual FairMQMessage* CreateMessage(size_t size); virtual FairMQMessage* CreateMessage(void* data, size_t size, fairmq_free_fn *ffn = NULL, void* hint = NULL); + virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, int numIoThreads); + virtual FairMQPoller* CreatePoller(const std::vector& channels); + virtual FairMQPoller* CreatePoller(std::map< std::string,std::vector >& channelsMap, std::initializer_list channelList); + virtual FairMQPoller* CreatePoller(FairMQSocket& dataSocket, FairMQSocket& cmdSocket); virtual ~FairMQTransportFactoryZMQ() {}; };