mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 16:46:47 +00:00
refactor: Prepare deprecation of non-namespaced types and headers
This commit is contained in:
parent
e3d3be888f
commit
139a223c31
|
@ -158,6 +158,7 @@ if(BUILD_FAIRMQ)
|
||||||
MemoryResourceTools.h
|
MemoryResourceTools.h
|
||||||
MemoryResources.h
|
MemoryResources.h
|
||||||
Message.h
|
Message.h
|
||||||
|
Parts.h
|
||||||
Plugin.h
|
Plugin.h
|
||||||
PluginManager.h
|
PluginManager.h
|
||||||
PluginServices.h
|
PluginServices.h
|
||||||
|
@ -216,24 +217,20 @@ if(BUILD_FAIRMQ)
|
||||||
# libFairMQ source files #
|
# libFairMQ source files #
|
||||||
##########################
|
##########################
|
||||||
set(FAIRMQ_SOURCE_FILES
|
set(FAIRMQ_SOURCE_FILES
|
||||||
|
Channel.cxx
|
||||||
|
Device.cxx
|
||||||
DeviceRunner.cxx
|
DeviceRunner.cxx
|
||||||
FairMQChannel.cxx
|
JSONParser.cxx
|
||||||
FairMQDevice.cxx
|
MemoryResources.cxx
|
||||||
FairMQLogger.cxx
|
|
||||||
FairMQMessage.cxx
|
|
||||||
FairMQPoller.cxx
|
|
||||||
FairMQSocket.cxx
|
|
||||||
FairMQTransportFactory.cxx
|
|
||||||
Plugin.cxx
|
Plugin.cxx
|
||||||
PluginManager.cxx
|
PluginManager.cxx
|
||||||
PluginServices.cxx
|
PluginServices.cxx
|
||||||
ProgOptions.cxx
|
ProgOptions.cxx
|
||||||
JSONParser.cxx
|
|
||||||
Properties.cxx
|
Properties.cxx
|
||||||
SuboptParser.cxx
|
SuboptParser.cxx
|
||||||
|
TransportFactory.cxx
|
||||||
plugins/config/Config.cxx
|
plugins/config/Config.cxx
|
||||||
plugins/control/Control.cxx
|
plugins/control/Control.cxx
|
||||||
MemoryResources.cxx
|
|
||||||
shmem/Manager.cxx
|
shmem/Manager.cxx
|
||||||
shmem/Monitor.cxx
|
shmem/Monitor.cxx
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,30 +1,27 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include "FairMQChannel.h"
|
#include <boost/algorithm/string.hpp> // join/split
|
||||||
|
#include <cstddef> // size_t
|
||||||
#include <fairmq/tools/Strings.h>
|
|
||||||
#include <fairmq/Properties.h>
|
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
#include <fairmq/Channel.h>
|
||||||
#include <boost/algorithm/string.hpp> // join/split
|
#include <fairmq/Properties.h>
|
||||||
|
#include <fairmq/Tools.h>
|
||||||
#include <cstddef> // size_t
|
#include <random>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <random>
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fair::mq;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound)
|
T GetPropertyOrDefault(const Properties& m, const string& k, const T& ifNotFound)
|
||||||
{
|
{
|
||||||
if (m.count(k)) {
|
if (m.count(k)) {
|
||||||
return boost::any_cast<T>(m.at(k));
|
return boost::any_cast<T>(m.at(k));
|
||||||
|
@ -32,39 +29,39 @@ T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T&
|
||||||
return ifNotFound;
|
return ifNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr fair::mq::Transport FairMQChannel::DefaultTransportType;
|
constexpr Transport Channel::DefaultTransportType;
|
||||||
constexpr const char* FairMQChannel::DefaultTransportName;
|
constexpr const char* Channel::DefaultTransportName;
|
||||||
constexpr const char* FairMQChannel::DefaultName;
|
constexpr const char* Channel::DefaultName;
|
||||||
constexpr const char* FairMQChannel::DefaultType;
|
constexpr const char* Channel::DefaultType;
|
||||||
constexpr const char* FairMQChannel::DefaultMethod;
|
constexpr const char* Channel::DefaultMethod;
|
||||||
constexpr const char* FairMQChannel::DefaultAddress;
|
constexpr const char* Channel::DefaultAddress;
|
||||||
constexpr int FairMQChannel::DefaultSndBufSize;
|
constexpr int Channel::DefaultSndBufSize;
|
||||||
constexpr int FairMQChannel::DefaultRcvBufSize;
|
constexpr int Channel::DefaultRcvBufSize;
|
||||||
constexpr int FairMQChannel::DefaultSndKernelSize;
|
constexpr int Channel::DefaultSndKernelSize;
|
||||||
constexpr int FairMQChannel::DefaultRcvKernelSize;
|
constexpr int Channel::DefaultRcvKernelSize;
|
||||||
constexpr int FairMQChannel::DefaultLinger;
|
constexpr int Channel::DefaultLinger;
|
||||||
constexpr int FairMQChannel::DefaultRateLogging;
|
constexpr int Channel::DefaultRateLogging;
|
||||||
constexpr int FairMQChannel::DefaultPortRangeMin;
|
constexpr int Channel::DefaultPortRangeMin;
|
||||||
constexpr int FairMQChannel::DefaultPortRangeMax;
|
constexpr int Channel::DefaultPortRangeMax;
|
||||||
constexpr bool FairMQChannel::DefaultAutoBind;
|
constexpr bool Channel::DefaultAutoBind;
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel()
|
Channel::Channel()
|
||||||
: FairMQChannel(DefaultName, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
: Channel(DefaultName, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const string& name)
|
Channel::Channel(const string& name)
|
||||||
: FairMQChannel(name, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
: Channel(name, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const string& type, const string& method, const string& address)
|
Channel::Channel(const string& type, const string& method, const string& address)
|
||||||
: FairMQChannel(DefaultName, type, method, address, nullptr)
|
: Channel(DefaultName, type, method, address, nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const string& name, const string& type, shared_ptr<FairMQTransportFactory> factory)
|
Channel::Channel(const string& name, const string& type, shared_ptr<TransportFactory> factory)
|
||||||
: FairMQChannel(name, type, DefaultMethod, DefaultAddress, factory)
|
: Channel(name, type, DefaultMethod, DefaultAddress, factory)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(string name, string type, string method, string address, shared_ptr<FairMQTransportFactory> factory)
|
Channel::Channel(string name, string type, string method, string address, shared_ptr<TransportFactory> factory)
|
||||||
: fTransportFactory(factory)
|
: fTransportFactory(factory)
|
||||||
, fTransportType(factory ? factory->GetType() : DefaultTransportType)
|
, fTransportType(factory ? factory->GetType() : DefaultTransportType)
|
||||||
, fSocket(factory ? factory->CreateSocket(type, name) : nullptr)
|
, fSocket(factory ? factory->CreateSocket(type, name) : nullptr)
|
||||||
|
@ -87,8 +84,8 @@ FairMQChannel::FairMQChannel(string name, string type, string method, string add
|
||||||
// LOG(warn) << "Constructing channel '" << fName << "'";
|
// LOG(warn) << "Constructing channel '" << fName << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const string& name, int index, const fair::mq::Properties& properties)
|
Channel::Channel(const string& name, int index, const Properties& properties)
|
||||||
: FairMQChannel(tools::ToString(name, "[", index, "]"), "unspecified", "unspecified", "unspecified", nullptr)
|
: Channel(tools::ToString(name, "[", index, "]"), "unspecified", "unspecified", "unspecified", nullptr)
|
||||||
{
|
{
|
||||||
string prefix(tools::ToString("chans.", name, ".", index, "."));
|
string prefix(tools::ToString("chans.", name, ".", index, "."));
|
||||||
|
|
||||||
|
@ -107,11 +104,11 @@ FairMQChannel::FairMQChannel(const string& name, int index, const fair::mq::Prop
|
||||||
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), DefaultAutoBind);
|
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), DefaultAutoBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
Channel::Channel(const Channel& chan)
|
||||||
: FairMQChannel(chan, chan.fName)
|
: Channel(chan, chan.fName)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel::FairMQChannel(const FairMQChannel& chan, string newName)
|
Channel::Channel(const Channel& chan, string newName)
|
||||||
: fTransportFactory(nullptr)
|
: fTransportFactory(nullptr)
|
||||||
, fTransportType(chan.fTransportType)
|
, fTransportType(chan.fTransportType)
|
||||||
, fSocket(nullptr)
|
, fSocket(nullptr)
|
||||||
|
@ -132,7 +129,7 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan, string newName)
|
||||||
, fMultipart(chan.fMultipart)
|
, fMultipart(chan.fMultipart)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
Channel& Channel::operator=(const Channel& chan)
|
||||||
{
|
{
|
||||||
if (this == &chan) {
|
if (this == &chan) {
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -160,7 +157,7 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQChannel::Validate()
|
bool Channel::Validate()
|
||||||
try {
|
try {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "Validating channel '" << fName << "'... ";
|
ss << "Validating channel '" << fName << "'... ";
|
||||||
|
@ -305,11 +302,11 @@ try {
|
||||||
LOG(debug) << ss.str();
|
LOG(debug) << ss.str();
|
||||||
return true;
|
return true;
|
||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
LOG(error) << "Exception caught in FairMQChannel::ValidateChannel: " << e.what();
|
LOG(error) << "Exception caught in Channel::ValidateChannel: " << e.what();
|
||||||
throw ChannelConfigurationError(tools::ToString(e.what()));
|
throw ChannelConfigurationError(tools::ToString(e.what()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQChannel::Init()
|
void Channel::Init()
|
||||||
{
|
{
|
||||||
fSocket = fTransportFactory->CreateSocket(fType, fName);
|
fSocket = fTransportFactory->CreateSocket(fType, fName);
|
||||||
|
|
||||||
|
@ -329,12 +326,12 @@ void FairMQChannel::Init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQChannel::ConnectEndpoint(const string& endpoint)
|
bool Channel::ConnectEndpoint(const string& endpoint)
|
||||||
{
|
{
|
||||||
return fSocket->Connect(endpoint);
|
return fSocket->Connect(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQChannel::BindEndpoint(string& endpoint)
|
bool Channel::BindEndpoint(string& endpoint)
|
||||||
{
|
{
|
||||||
// try to bind to the configured port. If it fails, try random one (if AutoBind is on).
|
// try to bind to the configured port. If it fails, try random one (if AutoBind is on).
|
||||||
if (fSocket->Bind(endpoint)) {
|
if (fSocket->Bind(endpoint)) {
|
||||||
|
@ -374,5 +371,6 @@ bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
443
fairmq/Channel.h
443
fairmq/Channel.h
|
@ -9,12 +9,449 @@
|
||||||
#ifndef FAIR_MQ_CHANNEL_H
|
#ifndef FAIR_MQ_CHANNEL_H
|
||||||
#define FAIR_MQ_CHANNEL_H
|
#define FAIR_MQ_CHANNEL_H
|
||||||
|
|
||||||
#include <FairMQChannel.h>
|
#include <cstdint> // int64_t
|
||||||
|
#include <fairmq/Message.h>
|
||||||
|
#include <fairmq/Parts.h>
|
||||||
|
#include <fairmq/Properties.h>
|
||||||
|
#include <fairmq/Socket.h>
|
||||||
|
#include <fairmq/TransportFactory.h>
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
#include <memory> // unique_ptr, shared_ptr
|
||||||
|
#include <mutex>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <utility> // std::move
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace fair::mq {
|
namespace fair::mq {
|
||||||
|
|
||||||
using Channel = FairMQChannel;
|
/**
|
||||||
|
* @class Channel Channel.h <fairmq/Channel.h>
|
||||||
|
* @brief Wrapper class for Socket and related methods
|
||||||
|
*
|
||||||
|
* The class is not thread-safe.
|
||||||
|
*/
|
||||||
|
class Channel
|
||||||
|
{
|
||||||
|
friend class Device;
|
||||||
|
|
||||||
} // namespace fair::mq
|
public:
|
||||||
|
/// Default constructor
|
||||||
|
Channel();
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param name Channel name
|
||||||
|
Channel(const std::string& name);
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||||
|
/// @param method Socket method (bind/connect)
|
||||||
|
/// @param address Network address to bind/connect to (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||||
|
Channel(const std::string& type, const std::string& method, const std::string& address);
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param name Channel name
|
||||||
|
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||||
|
/// @param factory TransportFactory
|
||||||
|
Channel(const std::string& name, const std::string& type, std::shared_ptr<TransportFactory> factory);
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param name Channel name
|
||||||
|
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||||
|
/// @param method Socket method (bind/connect)
|
||||||
|
/// @param address Network address to bind/connect to (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||||
|
/// @param factory TransportFactory
|
||||||
|
Channel(std::string name, std::string type, std::string method, std::string address, std::shared_ptr<TransportFactory> factory);
|
||||||
|
|
||||||
|
Channel(const std::string& name, int index, const Properties& properties);
|
||||||
|
|
||||||
|
/// Copy Constructor
|
||||||
|
Channel(const Channel&);
|
||||||
|
|
||||||
|
/// Copy Constructor (with new name)
|
||||||
|
Channel(const Channel&, std::string name);
|
||||||
|
|
||||||
|
/// Move constructor
|
||||||
|
// Channel(Channel&&) = delete;
|
||||||
|
|
||||||
|
/// Assignment operator
|
||||||
|
Channel& operator=(const Channel&);
|
||||||
|
|
||||||
|
/// Move assignment operator
|
||||||
|
// Channel& operator=(Channel&&) = delete;
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
virtual ~Channel() = default;
|
||||||
|
// { LOG(warn) << "Destroying channel '" << fName << "'"; }
|
||||||
|
|
||||||
|
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
|
||||||
|
Socket& GetSocket() const { assert(fSocket); return *fSocket; }
|
||||||
|
|
||||||
|
bool Bind(const std::string& address)
|
||||||
|
{
|
||||||
|
fMethod = "bind";
|
||||||
|
fAddress = address;
|
||||||
|
return fSocket->Bind(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connect(const std::string& address)
|
||||||
|
{
|
||||||
|
fMethod = "connect";
|
||||||
|
fAddress = address;
|
||||||
|
return fSocket->Connect(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get channel name
|
||||||
|
/// @return Returns full channel name (e.g. "data[0]")
|
||||||
|
std::string GetName() const { return fName; }
|
||||||
|
|
||||||
|
/// Get channel prefix
|
||||||
|
/// @return Returns channel prefix (e.g. "data" in "data[0]")
|
||||||
|
std::string GetPrefix() const
|
||||||
|
{
|
||||||
|
std::string prefix = fName;
|
||||||
|
prefix = prefix.erase(fName.rfind('['));
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get channel index
|
||||||
|
/// @return Returns channel index (e.g. 0 in "data[0]")
|
||||||
|
std::string GetIndex() const
|
||||||
|
{
|
||||||
|
std::string indexStr = fName;
|
||||||
|
indexStr.erase(indexStr.rfind(']'));
|
||||||
|
indexStr.erase(0, indexStr.rfind('[') + 1);
|
||||||
|
return indexStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get socket type
|
||||||
|
/// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||||
|
std::string GetType() const { return fType; }
|
||||||
|
|
||||||
|
/// Get socket method
|
||||||
|
/// @return Returns socket method (bind/connect)
|
||||||
|
std::string GetMethod() const { return fMethod; }
|
||||||
|
|
||||||
|
/// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||||
|
/// @return Returns socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||||
|
std::string GetAddress() const { return fAddress; }
|
||||||
|
|
||||||
|
/// Get channel transport name ("default", "zeromq" or "shmem")
|
||||||
|
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
|
||||||
|
std::string GetTransportName() const { return TransportName(fTransportType); }
|
||||||
|
|
||||||
|
/// Get channel transport type
|
||||||
|
/// @return Returns channel transport type
|
||||||
|
mq::Transport GetTransportType() const { return fTransportType; }
|
||||||
|
|
||||||
|
/// Get socket send buffer size (in number of messages)
|
||||||
|
/// @return Returns socket send buffer size (in number of messages)
|
||||||
|
int GetSndBufSize() const { return fSndBufSize; }
|
||||||
|
|
||||||
|
/// Get socket receive buffer size (in number of messages)
|
||||||
|
/// @return Returns socket receive buffer size (in number of messages)
|
||||||
|
int GetRcvBufSize() const { return fRcvBufSize; }
|
||||||
|
|
||||||
|
/// Get socket kernel transmit send buffer size (in bytes)
|
||||||
|
/// @return Returns socket kernel transmit send buffer size (in bytes)
|
||||||
|
int GetSndKernelSize() const { return fSndKernelSize; }
|
||||||
|
|
||||||
|
/// Get socket kernel transmit receive buffer size (in bytes)
|
||||||
|
/// @return Returns socket kernel transmit receive buffer size (in bytes)
|
||||||
|
int GetRcvKernelSize() const { return fRcvKernelSize; }
|
||||||
|
|
||||||
|
/// Get linger duration (in milliseconds)
|
||||||
|
/// @return Returns linger duration (in milliseconds)
|
||||||
|
int GetLinger() const { return fLinger; }
|
||||||
|
|
||||||
|
/// Get socket rate logging interval (in seconds)
|
||||||
|
/// @return Returns socket rate logging interval (in seconds)
|
||||||
|
int GetRateLogging() const { return fRateLogging; }
|
||||||
|
|
||||||
|
/// Get start of the port range for automatic binding
|
||||||
|
/// @return start of the port range
|
||||||
|
int GetPortRangeMin() const { return fPortRangeMin; }
|
||||||
|
|
||||||
|
/// Get end of the port range for automatic binding
|
||||||
|
/// @return end of the port range
|
||||||
|
int GetPortRangeMax() const { return fPortRangeMax; }
|
||||||
|
|
||||||
|
/// Set automatic binding (pick random port if bind fails)
|
||||||
|
/// @return true/false, true if automatic binding is enabled
|
||||||
|
bool GetAutoBind() const { return fAutoBind; }
|
||||||
|
|
||||||
|
/// Set channel name
|
||||||
|
/// @param name Arbitrary channel name
|
||||||
|
void UpdateName(const std::string& name) { fName = name; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket type
|
||||||
|
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||||
|
void UpdateType(const std::string& type) { fType = type; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket method
|
||||||
|
/// @param method Socket method (bind/connect)
|
||||||
|
void UpdateMethod(const std::string& method) { fMethod = method; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket address
|
||||||
|
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||||
|
void UpdateAddress(const std::string& address) { fAddress = address; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set channel transport
|
||||||
|
/// @param transport transport string ("default", "zeromq" or "shmem")
|
||||||
|
void UpdateTransport(const std::string& transport) { fTransportType = TransportType(transport); Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket send buffer size
|
||||||
|
/// @param sndBufSize Socket send buffer size (in number of messages)
|
||||||
|
void UpdateSndBufSize(const int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket receive buffer size
|
||||||
|
/// @param rcvBufSize Socket receive buffer size (in number of messages)
|
||||||
|
void UpdateRcvBufSize(const int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket kernel transmit send buffer size (in bytes)
|
||||||
|
/// @param sndKernelSize Socket send buffer size (in bytes)
|
||||||
|
void UpdateSndKernelSize(const int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket kernel transmit receive buffer size (in bytes)
|
||||||
|
/// @param rcvKernelSize Socket receive buffer size (in bytes)
|
||||||
|
void UpdateRcvKernelSize(const int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set linger duration (in milliseconds)
|
||||||
|
/// @param duration linger duration (in milliseconds)
|
||||||
|
void UpdateLinger(const int duration) { fLinger = duration; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set socket rate logging interval (in seconds)
|
||||||
|
/// @param rateLogging Socket rate logging interval (in seconds)
|
||||||
|
void UpdateRateLogging(const int rateLogging) { fRateLogging = rateLogging; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set start of the port range for automatic binding
|
||||||
|
/// @param minPort start of the port range
|
||||||
|
void UpdatePortRangeMin(const int minPort) { fPortRangeMin = minPort; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set end of the port range for automatic binding
|
||||||
|
/// @param maxPort end of the port range
|
||||||
|
void UpdatePortRangeMax(const int maxPort) { fPortRangeMax = maxPort; Invalidate(); }
|
||||||
|
|
||||||
|
/// Set automatic binding (pick random port if bind fails)
|
||||||
|
/// @param autobind true/false, true to enable automatic binding
|
||||||
|
void UpdateAutoBind(const bool autobind) { fAutoBind = autobind; Invalidate(); }
|
||||||
|
|
||||||
|
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
|
||||||
|
/// @return true if channel settings are valid, false otherwise.
|
||||||
|
bool IsValid() const { return fValid; }
|
||||||
|
|
||||||
|
/// Validates channel configuration
|
||||||
|
/// @return true if channel settings are valid, false otherwise.
|
||||||
|
bool Validate();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
bool ConnectEndpoint(const std::string& endpoint);
|
||||||
|
|
||||||
|
bool BindEndpoint(std::string& endpoint);
|
||||||
|
|
||||||
|
/// invalidates the channel (requires validation to be used again).
|
||||||
|
void Invalidate() { fValid = false; }
|
||||||
|
|
||||||
|
/// Sends a message to the socket queue.
|
||||||
|
/// @param msg Constant reference of unique_ptr to a Message
|
||||||
|
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||||
|
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Send(MessagePtr& msg, int sndTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
CheckSendCompatibility(msg);
|
||||||
|
return fSocket->Send(msg, sndTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receives a message from the socket queue.
|
||||||
|
/// @param msg Constant reference of unique_ptr to a Message
|
||||||
|
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||||
|
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Receive(MessagePtr& msg, int rcvTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
CheckReceiveCompatibility(msg);
|
||||||
|
return fSocket->Receive(msg, rcvTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a vector of messages
|
||||||
|
/// @param msgVec message vector reference
|
||||||
|
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||||
|
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Send(std::vector<MessagePtr>& msgVec, int sndTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
CheckSendCompatibility(msgVec);
|
||||||
|
return fSocket->Send(msgVec, sndTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receive a vector of messages
|
||||||
|
/// @param msgVec message vector reference
|
||||||
|
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||||
|
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Receive(std::vector<MessagePtr>& msgVec, int rcvTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
CheckReceiveCompatibility(msgVec);
|
||||||
|
return fSocket->Receive(msgVec, rcvTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send Parts
|
||||||
|
/// @param parts Parts reference
|
||||||
|
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||||
|
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Send(Parts& parts, int sndTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return Send(parts.fParts, sndTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receive Parts
|
||||||
|
/// @param parts Parts reference
|
||||||
|
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||||
|
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||||
|
int64_t Receive(Parts& parts, int rcvTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return Receive(parts.fParts, rcvTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long GetBytesTx() const { return fSocket->GetBytesTx(); }
|
||||||
|
unsigned long GetBytesRx() const { return fSocket->GetBytesRx(); }
|
||||||
|
unsigned long GetMessagesTx() const { return fSocket->GetMessagesTx(); }
|
||||||
|
unsigned long GetMessagesRx() const { return fSocket->GetMessagesRx(); }
|
||||||
|
|
||||||
|
auto Transport() -> TransportFactory* { return fTransportFactory.get(); };
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MessagePtr NewMessage(Args&&... args)
|
||||||
|
{
|
||||||
|
return Transport()->CreateMessage(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewSimpleMessage(const T& data)
|
||||||
|
{
|
||||||
|
return Transport()->NewSimpleMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewStaticMessage(const T& data)
|
||||||
|
{
|
||||||
|
return Transport()->NewStaticMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
UnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
||||||
|
{
|
||||||
|
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr mq::Transport DefaultTransportType = mq::Transport::DEFAULT;
|
||||||
|
static constexpr const char* DefaultTransportName = "default";
|
||||||
|
static constexpr const char* DefaultName = "";
|
||||||
|
static constexpr const char* DefaultType = "unspecified";
|
||||||
|
static constexpr const char* DefaultMethod = "unspecified";
|
||||||
|
static constexpr const char* DefaultAddress = "unspecified";
|
||||||
|
static constexpr int DefaultSndBufSize = 1000;
|
||||||
|
static constexpr int DefaultRcvBufSize = 1000;
|
||||||
|
static constexpr int DefaultSndKernelSize = 0;
|
||||||
|
static constexpr int DefaultRcvKernelSize = 0;
|
||||||
|
static constexpr int DefaultLinger = 500;
|
||||||
|
static constexpr int DefaultRateLogging = 1;
|
||||||
|
static constexpr int DefaultPortRangeMin = 22000;
|
||||||
|
static constexpr int DefaultPortRangeMax = 23000;
|
||||||
|
static constexpr bool DefaultAutoBind = true;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<TransportFactory> fTransportFactory;
|
||||||
|
mq::Transport fTransportType;
|
||||||
|
std::unique_ptr<Socket> fSocket;
|
||||||
|
|
||||||
|
std::string fName;
|
||||||
|
std::string fType;
|
||||||
|
std::string fMethod;
|
||||||
|
std::string fAddress;
|
||||||
|
int fSndBufSize;
|
||||||
|
int fRcvBufSize;
|
||||||
|
int fSndKernelSize;
|
||||||
|
int fRcvKernelSize;
|
||||||
|
int fLinger;
|
||||||
|
int fRateLogging;
|
||||||
|
int fPortRangeMin;
|
||||||
|
int fPortRangeMax;
|
||||||
|
bool fAutoBind;
|
||||||
|
|
||||||
|
bool fValid;
|
||||||
|
|
||||||
|
bool fMultipart;
|
||||||
|
|
||||||
|
void CheckSendCompatibility(MessagePtr& msg)
|
||||||
|
{
|
||||||
|
if (fTransportType != msg->GetType()) {
|
||||||
|
if (msg->GetSize() > 0) {
|
||||||
|
MessagePtr msgWrapper(NewMessage(
|
||||||
|
msg->GetData(),
|
||||||
|
msg->GetSize(),
|
||||||
|
[](void* /*data*/, void* _msg) { delete static_cast<Message*>(_msg); },
|
||||||
|
msg.get()
|
||||||
|
));
|
||||||
|
msg.release();
|
||||||
|
msg = move(msgWrapper);
|
||||||
|
} else {
|
||||||
|
MessagePtr newMsg(NewMessage());
|
||||||
|
msg = move(newMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckSendCompatibility(std::vector<MessagePtr>& msgVec)
|
||||||
|
{
|
||||||
|
for (auto& msg : msgVec) {
|
||||||
|
if (fTransportType != msg->GetType()) {
|
||||||
|
if (msg->GetSize() > 0) {
|
||||||
|
MessagePtr msgWrapper(NewMessage(
|
||||||
|
msg->GetData(),
|
||||||
|
msg->GetSize(),
|
||||||
|
[](void* /*data*/, void* _msg) { delete static_cast<Message*>(_msg); },
|
||||||
|
msg.get()
|
||||||
|
));
|
||||||
|
msg.release();
|
||||||
|
msg = move(msgWrapper);
|
||||||
|
} else {
|
||||||
|
MessagePtr newMsg(NewMessage());
|
||||||
|
msg = move(newMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckReceiveCompatibility(MessagePtr& msg)
|
||||||
|
{
|
||||||
|
if (fTransportType != msg->GetType()) {
|
||||||
|
MessagePtr newMsg(NewMessage());
|
||||||
|
msg = move(newMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckReceiveCompatibility(std::vector<MessagePtr>& msgVec)
|
||||||
|
{
|
||||||
|
for (auto& msg : msgVec) {
|
||||||
|
if (fTransportType != msg->GetType()) {
|
||||||
|
|
||||||
|
MessagePtr newMsg(NewMessage());
|
||||||
|
msg = move(newMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitTransport(std::shared_ptr<TransportFactory> factory)
|
||||||
|
{
|
||||||
|
fTransportFactory = factory;
|
||||||
|
fTransportType = factory->GetType();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQChannel [[deprecated("Use fair::mq::Channel")]] = fair::mq::Channel;
|
||||||
|
using FairMQChannel = fair::mq::Channel;
|
||||||
|
|
||||||
#endif // FAIR_MQ_CHANNEL_H
|
#endif // FAIR_MQ_CHANNEL_H
|
||||||
|
|
|
@ -1,51 +1,48 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2012-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <FairMQDevice.h>
|
#include <algorithm> // std::max
|
||||||
|
#include <boost/algorithm/string.hpp> // join/split
|
||||||
#include <fairmq/tools/RateLimit.h>
|
|
||||||
#include <fairmq/tools/Network.h>
|
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp> // join/split
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <fairmq/Device.h>
|
||||||
|
#include <fairmq/Tools.h>
|
||||||
|
#include <future>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iomanip>
|
|
||||||
#include <future>
|
namespace fair::mq {
|
||||||
#include <algorithm> // std::max
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fair::mq;
|
|
||||||
|
|
||||||
constexpr const char* FairMQDevice::DefaultId;
|
constexpr const char* Device::DefaultId;
|
||||||
constexpr int FairMQDevice::DefaultIOThreads;
|
constexpr int Device::DefaultIOThreads;
|
||||||
constexpr const char* FairMQDevice::DefaultTransportName;
|
constexpr const char* Device::DefaultTransportName;
|
||||||
constexpr fair::mq::Transport FairMQDevice::DefaultTransportType;
|
constexpr mq::Transport Device::DefaultTransportType;
|
||||||
constexpr const char* FairMQDevice::DefaultNetworkInterface;
|
constexpr const char* Device::DefaultNetworkInterface;
|
||||||
constexpr int FairMQDevice::DefaultInitTimeout;
|
constexpr int Device::DefaultInitTimeout;
|
||||||
constexpr uint64_t FairMQDevice::DefaultMaxRunTime;
|
constexpr uint64_t Device::DefaultMaxRunTime;
|
||||||
constexpr float FairMQDevice::DefaultRate;
|
constexpr float Device::DefaultRate;
|
||||||
constexpr const char* FairMQDevice::DefaultSession;
|
constexpr const char* Device::DefaultSession;
|
||||||
|
|
||||||
struct StateSubscription
|
struct StateSubscription
|
||||||
{
|
{
|
||||||
fair::mq::StateMachine& fStateMachine;
|
StateMachine& fStateMachine;
|
||||||
fair::mq::StateQueue& fStateQueue;
|
StateQueue& fStateQueue;
|
||||||
string fId;
|
string fId;
|
||||||
|
|
||||||
explicit StateSubscription(string id, fair::mq::StateMachine& stateMachine, fair::mq::StateQueue& stateQueue)
|
explicit StateSubscription(string id, StateMachine& stateMachine, StateQueue& stateQueue)
|
||||||
: fStateMachine(stateMachine)
|
: fStateMachine(stateMachine)
|
||||||
, fStateQueue(stateQueue)
|
, fStateQueue(stateQueue)
|
||||||
, fId(std::move(id))
|
, fId(std::move(id))
|
||||||
{
|
{
|
||||||
fStateMachine.SubscribeToStateChange(fId, [&](fair::mq::State state) {
|
fStateMachine.SubscribeToStateChange(fId, [&](State state) {
|
||||||
fStateQueue.Push(state);
|
fStateQueue.Push(state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -55,23 +52,23 @@ struct StateSubscription
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FairMQDevice::FairMQDevice()
|
Device::Device()
|
||||||
: FairMQDevice(nullptr, {0, 0, 0})
|
: Device(nullptr, {0, 0, 0})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQDevice::FairMQDevice(ProgOptions& config)
|
Device::Device(ProgOptions& config)
|
||||||
: FairMQDevice(&config, {0, 0, 0})
|
: Device(&config, {0, 0, 0})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQDevice::FairMQDevice(const tools::Version version)
|
Device::Device(const tools::Version version)
|
||||||
: FairMQDevice(nullptr, version)
|
: Device(nullptr, version)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQDevice::FairMQDevice(ProgOptions& config, const tools::Version version)
|
Device::Device(ProgOptions& config, const tools::Version version)
|
||||||
: FairMQDevice(&config, version)
|
: Device(&config, version)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
|
Device::Device(ProgOptions* config, const tools::Version version)
|
||||||
: fTransportFactory(nullptr)
|
: fTransportFactory(nullptr)
|
||||||
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
|
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
|
||||||
, fConfig(config ? config : fInternalConfig.get())
|
, fConfig(config ? config : fInternalConfig.get())
|
||||||
|
@ -97,34 +94,34 @@ FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fStateMachine.HandleStates([&](fair::mq::State state) {
|
fStateMachine.HandleStates([&](State state) {
|
||||||
LOG(trace) << "device notified on new state: " << state;
|
LOG(trace) << "device notified on new state: " << state;
|
||||||
|
|
||||||
fStateQueue.Push(state);
|
fStateQueue.Push(state);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case fair::mq::State::InitializingDevice:
|
case State::InitializingDevice:
|
||||||
InitWrapper();
|
InitWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::Binding:
|
case State::Binding:
|
||||||
BindWrapper();
|
BindWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::Connecting:
|
case State::Connecting:
|
||||||
ConnectWrapper();
|
ConnectWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::InitializingTask:
|
case State::InitializingTask:
|
||||||
InitTaskWrapper();
|
InitTaskWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::Running:
|
case State::Running:
|
||||||
RunWrapper();
|
RunWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::ResettingTask:
|
case State::ResettingTask:
|
||||||
ResetTaskWrapper();
|
ResetTaskWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::ResettingDevice:
|
case State::ResettingDevice:
|
||||||
ResetWrapper();
|
ResetWrapper();
|
||||||
break;
|
break;
|
||||||
case fair::mq::State::Exiting:
|
case State::Exiting:
|
||||||
Exit();
|
Exit();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -136,7 +133,7 @@ FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
|
||||||
fStateMachine.Start();
|
fStateMachine.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::TransitionTo(const fair::mq::State s)
|
void Device::TransitionTo(const State s)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fTransitionMtx);
|
lock_guard<mutex> lock(fTransitionMtx);
|
||||||
|
@ -147,7 +144,7 @@ void FairMQDevice::TransitionTo(const fair::mq::State s)
|
||||||
fTransitioning = true;
|
fTransitioning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
using fair::mq::State;
|
using mq::State;
|
||||||
|
|
||||||
StateQueue sq;
|
StateQueue sq;
|
||||||
StateSubscription ss(tools::ToString(fId, ".TransitionTo"), fStateMachine, sq);
|
StateSubscription ss(tools::ToString(fId, ".TransitionTo"), fStateMachine, sq);
|
||||||
|
@ -203,7 +200,7 @@ void FairMQDevice::TransitionTo(const fair::mq::State s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::InitWrapper()
|
void Device::InitWrapper()
|
||||||
{
|
{
|
||||||
// run initialization once CompleteInit transition is requested
|
// run initialization once CompleteInit transition is requested
|
||||||
fStateMachine.WaitForPendingState();
|
fStateMachine.WaitForPendingState();
|
||||||
|
@ -217,7 +214,7 @@ void FairMQDevice::InitWrapper()
|
||||||
fInitializationTimeoutInS = fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout);
|
fInitializationTimeoutInS = fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fDefaultTransportType = fair::mq::TransportTypes.at(fConfig->GetProperty<string>("transport", DefaultTransportName));
|
fDefaultTransportType = TransportTypes.at(fConfig->GetProperty<string>("transport", DefaultTransportName));
|
||||||
} catch (const exception& e) {
|
} catch (const exception& e) {
|
||||||
LOG(error) << "exception: " << e.what();
|
LOG(error) << "exception: " << e.what();
|
||||||
LOG(error) << "invalid transport type provided: " << fConfig->GetProperty<string>("transport", "not provided");
|
LOG(error) << "invalid transport type provided: " << fConfig->GetProperty<string>("transport", "not provided");
|
||||||
|
@ -231,7 +228,7 @@ void FairMQDevice::InitWrapper()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(debug) << "Setting '" << fair::mq::TransportNames.at(fDefaultTransportType) << "' as default transport for the device";
|
LOG(debug) << "Setting '" << TransportNames.at(fDefaultTransportType) << "' as default transport for the device";
|
||||||
fTransportFactory = AddTransport(fDefaultTransportType);
|
fTransportFactory = AddTransport(fDefaultTransportType);
|
||||||
|
|
||||||
string networkInterface = fConfig->GetProperty<string>("network-interface", DefaultNetworkInterface);
|
string networkInterface = fConfig->GetProperty<string>("network-interface", DefaultNetworkInterface);
|
||||||
|
@ -241,7 +238,7 @@ void FairMQDevice::InitWrapper()
|
||||||
int subChannelIndex = 0;
|
int subChannelIndex = 0;
|
||||||
for (auto& subChannel : channel.second) {
|
for (auto& subChannel : channel.second) {
|
||||||
// set channel transport
|
// set channel transport
|
||||||
LOG(debug) << "Initializing transport for channel " << subChannel.fName << ": " << fair::mq::TransportNames.at(subChannel.fTransportType);
|
LOG(debug) << "Initializing transport for channel " << subChannel.fName << ": " << TransportNames.at(subChannel.fTransportType);
|
||||||
subChannel.InitTransport(AddTransport(subChannel.fTransportType));
|
subChannel.InitTransport(AddTransport(subChannel.fTransportType));
|
||||||
|
|
||||||
if (subChannel.fMethod == "bind") {
|
if (subChannel.fMethod == "bind") {
|
||||||
|
@ -278,7 +275,7 @@ void FairMQDevice::InitWrapper()
|
||||||
// ChangeState(Transition::Auto);
|
// ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::BindWrapper()
|
void Device::BindWrapper()
|
||||||
{
|
{
|
||||||
// Bind channels. Here one run is enough, because bind settings should be available locally
|
// Bind channels. Here one run is enough, because bind settings should be available locally
|
||||||
// If necessary this could be handled in the same way as the connecting channels
|
// If necessary this could be handled in the same way as the connecting channels
|
||||||
|
@ -294,7 +291,7 @@ void FairMQDevice::BindWrapper()
|
||||||
ChangeState(Transition::Auto);
|
ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::ConnectWrapper()
|
void Device::ConnectWrapper()
|
||||||
{
|
{
|
||||||
// go over the list of channels until all are initialized (and removed from the uninitialized list)
|
// go over the list of channels until all are initialized (and removed from the uninitialized list)
|
||||||
int numAttempts = 1;
|
int numAttempts = 1;
|
||||||
|
@ -331,7 +328,7 @@ void FairMQDevice::ConnectWrapper()
|
||||||
ChangeState(Transition::Auto);
|
ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::AttachChannels(vector<FairMQChannel*>& chans)
|
void Device::AttachChannels(vector<Channel*>& chans)
|
||||||
{
|
{
|
||||||
auto itr = chans.begin();
|
auto itr = chans.begin();
|
||||||
|
|
||||||
|
@ -351,7 +348,7 @@ void FairMQDevice::AttachChannels(vector<FairMQChannel*>& chans)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQDevice::AttachChannel(FairMQChannel& chan)
|
bool Device::AttachChannel(Channel& chan)
|
||||||
{
|
{
|
||||||
vector<string> endpoints;
|
vector<string> endpoints;
|
||||||
string chanAddress = chan.GetAddress();
|
string chanAddress = chan.GetAddress();
|
||||||
|
@ -424,19 +421,19 @@ bool FairMQDevice::AttachChannel(FairMQChannel& chan)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::InitTaskWrapper()
|
void Device::InitTaskWrapper()
|
||||||
{
|
{
|
||||||
InitTask();
|
InitTask();
|
||||||
|
|
||||||
ChangeState(Transition::Auto);
|
ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::RunWrapper()
|
void Device::RunWrapper()
|
||||||
{
|
{
|
||||||
LOG(info) << "DEVICE: Running...";
|
LOG(info) << "DEVICE: Running...";
|
||||||
|
|
||||||
// start the rate logger thread
|
// start the rate logger thread
|
||||||
future<void> rateLogger = async(launch::async, &FairMQDevice::LogSocketRates, this);
|
future<void> rateLogger = async(launch::async, &Device::LogSocketRates, this);
|
||||||
|
|
||||||
// notify transports to resume transfers
|
// notify transports to resume transfers
|
||||||
for (auto& t : fTransports) {
|
for (auto& t : fTransports) {
|
||||||
|
@ -486,7 +483,7 @@ void FairMQDevice::RunWrapper()
|
||||||
rateLogger.get();
|
rateLogger.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::HandleSingleChannelInput()
|
void Device::HandleSingleChannelInput()
|
||||||
{
|
{
|
||||||
bool proceed = true;
|
bool proceed = true;
|
||||||
|
|
||||||
|
@ -501,14 +498,14 @@ void FairMQDevice::HandleSingleChannelInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::HandleMultipleChannelInput()
|
void Device::HandleMultipleChannelInput()
|
||||||
{
|
{
|
||||||
// check if more than one transport is used
|
// check if more than one transport is used
|
||||||
fMultitransportInputs.clear();
|
fMultitransportInputs.clear();
|
||||||
for (const auto& k : fInputChannelKeys) {
|
for (const auto& k : fInputChannelKeys) {
|
||||||
fair::mq::Transport t = fChannels.at(k).at(0).fTransportType;
|
mq::Transport t = fChannels.at(k).at(0).fTransportType;
|
||||||
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
|
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
|
||||||
fMultitransportInputs.insert(pair<fair::mq::Transport, vector<string>>(t, vector<string>()));
|
fMultitransportInputs.insert(pair<mq::Transport, vector<string>>(t, vector<string>()));
|
||||||
fMultitransportInputs.at(t).push_back(k);
|
fMultitransportInputs.at(t).push_back(k);
|
||||||
} else {
|
} else {
|
||||||
fMultitransportInputs.at(t).push_back(k);
|
fMultitransportInputs.at(t).push_back(k);
|
||||||
|
@ -533,7 +530,7 @@ void FairMQDevice::HandleMultipleChannelInput()
|
||||||
} else { // otherwise poll directly
|
} else { // otherwise poll directly
|
||||||
bool proceed = true;
|
bool proceed = true;
|
||||||
|
|
||||||
FairMQPollerPtr poller(fChannels.at(fInputChannelKeys.at(0)).at(0).fTransportFactory->CreatePoller(fChannels, fInputChannelKeys));
|
PollerPtr poller(fChannels.at(fInputChannelKeys.at(0)).at(0).fTransportFactory->CreatePoller(fChannels, fInputChannelKeys));
|
||||||
|
|
||||||
while (!NewStatePending() && proceed) {
|
while (!NewStatePending() && proceed) {
|
||||||
poller->Poll(200);
|
poller->Poll(200);
|
||||||
|
@ -561,14 +558,14 @@ void FairMQDevice::HandleMultipleChannelInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::HandleMultipleTransportInput()
|
void Device::HandleMultipleTransportInput()
|
||||||
{
|
{
|
||||||
vector<thread> threads;
|
vector<thread> threads;
|
||||||
|
|
||||||
fMultitransportProceed = true;
|
fMultitransportProceed = true;
|
||||||
|
|
||||||
for (const auto& i : fMultitransportInputs) {
|
for (const auto& i : fMultitransportInputs) {
|
||||||
threads.emplace_back(thread(&FairMQDevice::PollForTransport, this, fTransports.at(i.first).get(), i.second));
|
threads.emplace_back(thread(&Device::PollForTransport, this, fTransports.at(i.first).get(), i.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (thread& t : threads) {
|
for (thread& t : threads) {
|
||||||
|
@ -576,10 +573,10 @@ void FairMQDevice::HandleMultipleTransportInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::PollForTransport(const FairMQTransportFactory* factory, const vector<string>& channelKeys)
|
void Device::PollForTransport(const TransportFactory* factory, const vector<string>& channelKeys)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
FairMQPollerPtr poller(factory->CreatePoller(fChannels, channelKeys));
|
PollerPtr poller(factory->CreatePoller(fChannels, channelKeys));
|
||||||
|
|
||||||
while (!NewStatePending() && fMultitransportProceed) {
|
while (!NewStatePending() && fMultitransportProceed) {
|
||||||
poller->Poll(500);
|
poller->Poll(500);
|
||||||
|
@ -610,14 +607,14 @@ void FairMQDevice::PollForTransport(const FairMQTransportFactory* factory, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
LOG(error) << "FairMQDevice::PollForTransport() failed: " << e.what() << ", going to ERROR state.";
|
LOG(error) << "fair::mq::Device::PollForTransport() failed: " << e.what() << ", going to ERROR state.";
|
||||||
throw runtime_error(tools::ToString("FairMQDevice::PollForTransport() failed: ", e.what(), ", going to ERROR state."));
|
throw runtime_error(tools::ToString("fair::mq::Device::PollForTransport() failed: ", e.what(), ", going to ERROR state."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQDevice::HandleMsgInput(const string& chName, const InputMsgCallback& callback, int i)
|
bool Device::HandleMsgInput(const string& chName, const InputMsgCallback& callback, int i)
|
||||||
{
|
{
|
||||||
unique_ptr<FairMQMessage> input(fChannels.at(chName).at(i).fTransportFactory->CreateMessage());
|
unique_ptr<Message> input(fChannels.at(chName).at(i).fTransportFactory->CreateMessage());
|
||||||
|
|
||||||
if (Receive(input, chName, i) >= 0) {
|
if (Receive(input, chName, i) >= 0) {
|
||||||
return callback(input, i);
|
return callback(input, i);
|
||||||
|
@ -626,9 +623,9 @@ bool FairMQDevice::HandleMsgInput(const string& chName, const InputMsgCallback&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQDevice::HandleMultipartInput(const string& chName, const InputMultipartCallback& callback, int i)
|
bool Device::HandleMultipartInput(const string& chName, const InputMultipartCallback& callback, int i)
|
||||||
{
|
{
|
||||||
FairMQParts input;
|
Parts input;
|
||||||
|
|
||||||
if (Receive(input, chName, i) >= 0) {
|
if (Receive(input, chName, i) >= 0) {
|
||||||
return callback(input, i);
|
return callback(input, i);
|
||||||
|
@ -637,34 +634,34 @@ bool FairMQDevice::HandleMultipartInput(const string& chName, const InputMultipa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<FairMQTransportFactory> FairMQDevice::AddTransport(fair::mq::Transport transport)
|
shared_ptr<TransportFactory> Device::AddTransport(mq::Transport transport)
|
||||||
{
|
{
|
||||||
if (transport == fair::mq::Transport::DEFAULT) {
|
if (transport == mq::Transport::DEFAULT) {
|
||||||
transport = fDefaultTransportType;
|
transport = fDefaultTransportType;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i = fTransports.find(transport);
|
auto i = fTransports.find(transport);
|
||||||
|
|
||||||
if (i == fTransports.end()) {
|
if (i == fTransports.end()) {
|
||||||
LOG(debug) << "Adding '" << fair::mq::TransportNames.at(transport) << "' transport";
|
LOG(debug) << "Adding '" << TransportNames.at(transport) << "' transport";
|
||||||
auto tr = FairMQTransportFactory::CreateTransportFactory(fair::mq::TransportNames.at(transport), fId, fConfig);
|
auto tr = TransportFactory::CreateTransportFactory(TransportNames.at(transport), fId, fConfig);
|
||||||
fTransports.insert({transport, tr});
|
fTransports.insert({transport, tr});
|
||||||
return tr;
|
return tr;
|
||||||
} else {
|
} else {
|
||||||
LOG(debug) << "Reusing existing '" << fair::mq::TransportNames.at(transport) << "' transport";
|
LOG(debug) << "Reusing existing '" << TransportNames.at(transport) << "' transport";
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::SetConfig(ProgOptions& config)
|
void Device::SetConfig(ProgOptions& config)
|
||||||
{
|
{
|
||||||
fInternalConfig.reset();
|
fInternalConfig.reset();
|
||||||
fConfig = &config;
|
fConfig = &config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::LogSocketRates()
|
void Device::LogSocketRates()
|
||||||
{
|
{
|
||||||
vector<FairMQChannel*> filteredChannels;
|
vector<Channel*> filteredChannels;
|
||||||
vector<string> filteredChannelNames;
|
vector<string> filteredChannelNames;
|
||||||
vector<int> logIntervals;
|
vector<int> logIntervals;
|
||||||
vector<int> intervalCounters;
|
vector<int> intervalCounters;
|
||||||
|
@ -760,21 +757,21 @@ void FairMQDevice::LogSocketRates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::UnblockTransports()
|
void Device::UnblockTransports()
|
||||||
{
|
{
|
||||||
for (auto& transport : fTransports) {
|
for (auto& transport : fTransports) {
|
||||||
transport.second->Interrupt();
|
transport.second->Interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::ResetTaskWrapper()
|
void Device::ResetTaskWrapper()
|
||||||
{
|
{
|
||||||
ResetTask();
|
ResetTask();
|
||||||
|
|
||||||
ChangeState(Transition::Auto);
|
ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FairMQDevice::ResetWrapper()
|
void Device::ResetWrapper()
|
||||||
{
|
{
|
||||||
for (auto& transport : fTransports) {
|
for (auto& transport : fTransports) {
|
||||||
transport.second->Reset();
|
transport.second->Reset();
|
||||||
|
@ -788,9 +785,11 @@ void FairMQDevice::ResetWrapper()
|
||||||
ChangeState(Transition::Auto);
|
ChangeState(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQDevice::~FairMQDevice()
|
Device::~Device()
|
||||||
{
|
{
|
||||||
UnsubscribeFromNewTransition("device");
|
UnsubscribeFromNewTransition("device");
|
||||||
fStateMachine.StopHandlingStates();
|
fStateMachine.StopHandlingStates();
|
||||||
LOG(debug) << "Shutting down device " << fId;
|
LOG(debug) << "Shutting down device " << fId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
622
fairmq/Device.h
622
fairmq/Device.h
|
@ -9,13 +9,627 @@
|
||||||
#ifndef FAIR_MQ_DEVICE_H
|
#ifndef FAIR_MQ_DEVICE_H
|
||||||
#define FAIR_MQ_DEVICE_H
|
#define FAIR_MQ_DEVICE_H
|
||||||
|
|
||||||
#include <FairMQDevice.h>
|
#include <algorithm> // find
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <fairlogger/Logger.h>
|
||||||
|
#include <fairmq/Channel.h>
|
||||||
|
#include <fairmq/Message.h>
|
||||||
|
#include <fairmq/Parts.h>
|
||||||
|
#include <fairmq/ProgOptions.h>
|
||||||
|
#include <fairmq/StateMachine.h>
|
||||||
|
#include <fairmq/StateQueue.h>
|
||||||
|
#include <fairmq/Tools.h>
|
||||||
|
#include <fairmq/TransportFactory.h>
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory> // unique_ptr
|
||||||
|
#include <mutex>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility> // pair
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace fair::mq
|
namespace fair::mq {
|
||||||
|
|
||||||
|
using ChannelMap = std::unordered_map<std::string, std::vector<Channel>>;
|
||||||
|
|
||||||
|
struct OngoingTransition : std::runtime_error
|
||||||
{
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
using Device = ::FairMQDevice;
|
using InputMsgCallback = std::function<bool(MessagePtr&, int)>;
|
||||||
|
|
||||||
} // namespace fair::mq
|
using InputMultipartCallback = std::function<bool(Parts&, int)>;
|
||||||
|
|
||||||
|
class Device
|
||||||
|
{
|
||||||
|
friend class Channel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Device();
|
||||||
|
Device(ProgOptions& config);
|
||||||
|
Device(const tools::Version version);
|
||||||
|
Device(ProgOptions& config, const tools::Version version);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Device(ProgOptions* config, const tools::Version version);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Device(const Device&) = delete;
|
||||||
|
Device operator=(const Device&) = delete;
|
||||||
|
virtual ~Device();
|
||||||
|
|
||||||
|
/// Outputs the socket transfer rates
|
||||||
|
virtual void LogSocketRates();
|
||||||
|
|
||||||
|
template<typename Serializer, typename DataType, typename... Args>
|
||||||
|
[[deprecated]] void Serialize(Message& msg, DataType&& data, Args&&... args) const
|
||||||
|
{
|
||||||
|
Serializer().Serialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Deserializer, typename DataType, typename... Args>
|
||||||
|
[[deprecated]] void Deserialize(Message& msg, DataType&& data, Args&&... args) const
|
||||||
|
{
|
||||||
|
Deserializer().Deserialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shorthand method to send `msg` on `chan` at index `i`
|
||||||
|
/// @param msg message reference
|
||||||
|
/// @param chan channel name
|
||||||
|
/// @param i channel index
|
||||||
|
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via
|
||||||
|
/// state change)), 0 will not wait (return immediately if cannot send)
|
||||||
|
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out,
|
||||||
|
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by
|
||||||
|
/// requested state change)
|
||||||
|
int64_t Send(MessagePtr& msg,
|
||||||
|
const std::string& channel,
|
||||||
|
const int index = 0,
|
||||||
|
int sndTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).Send(msg, sndTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shorthand method to receive `msg` on `chan` at index `i`
|
||||||
|
/// @param msg message reference
|
||||||
|
/// @param chan channel name
|
||||||
|
/// @param i channel index
|
||||||
|
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g.
|
||||||
|
/// via state change)), 0 will not wait (return immediately if cannot receive)
|
||||||
|
/// @return Number of bytes that have been received, TransferCode::timeout if timed out,
|
||||||
|
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by
|
||||||
|
/// requested state change)
|
||||||
|
int64_t Receive(MessagePtr& msg,
|
||||||
|
const std::string& channel,
|
||||||
|
const int index = 0,
|
||||||
|
int rcvTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shorthand method to send Parts on `chan` at index `i`
|
||||||
|
/// @param parts parts reference
|
||||||
|
/// @param chan channel name
|
||||||
|
/// @param i channel index
|
||||||
|
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via
|
||||||
|
/// state change)), 0 will not wait (return immediately if cannot send)
|
||||||
|
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out,
|
||||||
|
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by
|
||||||
|
/// requested state change)
|
||||||
|
int64_t Send(Parts& parts,
|
||||||
|
const std::string& channel,
|
||||||
|
const int index = 0,
|
||||||
|
int sndTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).Send(parts.fParts, sndTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shorthand method to receive Parts on `chan` at index `i`
|
||||||
|
/// @param parts parts reference
|
||||||
|
/// @param chan channel name
|
||||||
|
/// @param i channel index
|
||||||
|
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g.
|
||||||
|
/// via state change)), 0 will not wait (return immediately if cannot receive)
|
||||||
|
/// @return Number of bytes that have been received, TransferCode::timeout if timed out,
|
||||||
|
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by
|
||||||
|
/// requested state change)
|
||||||
|
int64_t Receive(Parts& parts,
|
||||||
|
const std::string& channel,
|
||||||
|
const int index = 0,
|
||||||
|
int rcvTimeoutInMs = -1)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Getter for default transport factory
|
||||||
|
auto Transport() const -> TransportFactory* { return fTransportFactory.get(); }
|
||||||
|
|
||||||
|
// creates message with the default device transport
|
||||||
|
template<typename... Args>
|
||||||
|
MessagePtr NewMessage(Args&&... args)
|
||||||
|
{
|
||||||
|
return Transport()->CreateMessage(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates message with the transport of the specified channel
|
||||||
|
template<typename... Args>
|
||||||
|
MessagePtr NewMessageFor(const std::string& channel, int index, Args&&... args)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).NewMessage(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a message that will not be cleaned up after transfer, with the default device
|
||||||
|
// transport
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewStaticMessage(const T& data)
|
||||||
|
{
|
||||||
|
return Transport()->NewStaticMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a message that will not be cleaned up after transfer, with the transport of the
|
||||||
|
// specified channel
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewStaticMessageFor(const std::string& channel, int index, const T& data)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).NewStaticMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a message with a copy of the provided data, with the default device transport
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewSimpleMessage(const T& data)
|
||||||
|
{
|
||||||
|
return Transport()->NewSimpleMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a message with a copy of the provided data, with the transport of the specified
|
||||||
|
// channel
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewSimpleMessageFor(const std::string& channel, int index, const T& data)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).NewSimpleMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates unamanaged region with the default device transport
|
||||||
|
template<typename... Args>
|
||||||
|
UnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
||||||
|
{
|
||||||
|
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates unmanaged region with the transport of the specified channel
|
||||||
|
template<typename... Args>
|
||||||
|
UnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, Args&&... args)
|
||||||
|
{
|
||||||
|
return GetChannel(channel, index).NewUnmanagedRegion(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
PollerPtr NewPoller(const Ts&... inputs)
|
||||||
|
{
|
||||||
|
std::vector<std::string> chans{inputs...};
|
||||||
|
|
||||||
|
// if more than one channel provided, check compatibility
|
||||||
|
if (chans.size() > 1) {
|
||||||
|
mq::Transport type = GetChannel(chans.at(0), 0).Transport()->GetType();
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < chans.size(); ++i) {
|
||||||
|
if (type != GetChannel(chans.at(i), 0).Transport()->GetType()) {
|
||||||
|
LOG(error) << "poller failed: different transports within same poller are not "
|
||||||
|
"yet supported. Going to ERROR state.";
|
||||||
|
throw std::runtime_error("poller failed: different transports within same "
|
||||||
|
"poller are not yet supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetChannel(chans.at(0), 0).Transport()->CreatePoller(fChannels, chans);
|
||||||
|
}
|
||||||
|
|
||||||
|
PollerPtr NewPoller(const std::vector<Channel*>& channels)
|
||||||
|
{
|
||||||
|
// if more than one channel provided, check compatibility
|
||||||
|
if (channels.size() > 1) {
|
||||||
|
mq::Transport type = channels.at(0)->Transport()->GetType();
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < channels.size(); ++i) {
|
||||||
|
if (type != channels.at(i)->Transport()->GetType()) {
|
||||||
|
LOG(error) << "poller failed: different transports within same poller are not "
|
||||||
|
"yet supported. Going to ERROR state.";
|
||||||
|
throw std::runtime_error("poller failed: different transports within same "
|
||||||
|
"poller are not yet supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels.at(0)->Transport()->CreatePoller(channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a transport to the device if it doesn't exist
|
||||||
|
/// @param transport Transport string ("zeromq"/"shmem")
|
||||||
|
std::shared_ptr<TransportFactory> AddTransport(const mq::Transport transport);
|
||||||
|
|
||||||
|
/// Assigns config to the device
|
||||||
|
void SetConfig(ProgOptions& config);
|
||||||
|
/// Get pointer to the config
|
||||||
|
ProgOptions* GetConfig() const { return fConfig; }
|
||||||
|
|
||||||
|
// overload to easily bind member functions
|
||||||
|
template<typename T>
|
||||||
|
void OnData(const std::string& channelName,
|
||||||
|
bool (T::*memberFunction)(MessagePtr& msg, int index))
|
||||||
|
{
|
||||||
|
fDataCallbacks = true;
|
||||||
|
fMsgInputs.insert(
|
||||||
|
std::make_pair(channelName, [this, memberFunction](MessagePtr& msg, int index) {
|
||||||
|
return (static_cast<T*>(this)->*memberFunction)(msg, index);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName)
|
||||||
|
== fInputChannelKeys.end()) {
|
||||||
|
fInputChannelKeys.push_back(channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnData(const std::string& channelName, InputMsgCallback callback)
|
||||||
|
{
|
||||||
|
fDataCallbacks = true;
|
||||||
|
fMsgInputs.insert(make_pair(channelName, callback));
|
||||||
|
|
||||||
|
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName)
|
||||||
|
== fInputChannelKeys.end()) {
|
||||||
|
fInputChannelKeys.push_back(channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// overload to easily bind member functions
|
||||||
|
template<typename T>
|
||||||
|
void OnData(const std::string& channelName, bool (T::*memberFunction)(Parts& parts, int index))
|
||||||
|
{
|
||||||
|
fDataCallbacks = true;
|
||||||
|
fMultipartInputs.insert(
|
||||||
|
std::make_pair(channelName, [this, memberFunction](Parts& parts, int index) {
|
||||||
|
return (static_cast<T*>(this)->*memberFunction)(parts, index);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName)
|
||||||
|
== fInputChannelKeys.end()) {
|
||||||
|
fInputChannelKeys.push_back(channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnData(const std::string& channelName, InputMultipartCallback callback)
|
||||||
|
{
|
||||||
|
fDataCallbacks = true;
|
||||||
|
fMultipartInputs.insert(make_pair(channelName, callback));
|
||||||
|
|
||||||
|
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName)
|
||||||
|
== fInputChannelKeys.end()) {
|
||||||
|
fInputChannelKeys.push_back(channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel& GetChannel(const std::string& channelName, const int index = 0)
|
||||||
|
try {
|
||||||
|
return fChannels.at(channelName).at(index);
|
||||||
|
} catch (const std::out_of_range& oor) {
|
||||||
|
LOG(error)
|
||||||
|
<< "requested channel has not been configured? check channel names/configuration.";
|
||||||
|
LOG(error) << "channel: " << channelName << ", index: " << index;
|
||||||
|
LOG(error) << "out of range: " << oor.what();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RegisterChannelEndpoints() {}
|
||||||
|
|
||||||
|
bool RegisterChannelEndpoint(const std::string& channelName,
|
||||||
|
uint16_t minNumSubChannels = 1,
|
||||||
|
uint16_t maxNumSubChannels = 1)
|
||||||
|
{
|
||||||
|
bool ok = fChannelRegistry
|
||||||
|
.insert(std::make_pair(channelName,
|
||||||
|
std::make_pair(minNumSubChannels, maxNumSubChannels)))
|
||||||
|
.second;
|
||||||
|
if (!ok) {
|
||||||
|
LOG(warn) << "Registering channel: name already registered: \"" << channelName << "\"";
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintRegisteredChannels()
|
||||||
|
{
|
||||||
|
if (fChannelRegistry.empty()) {
|
||||||
|
LOGV(info, verylow) << "no channels registered.";
|
||||||
|
} else {
|
||||||
|
for (const auto& c : fChannelRegistry) {
|
||||||
|
LOGV(info, verylow) << c.first << ":" << c.second.first << ":" << c.second.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetId(const std::string& id) { fId = id; }
|
||||||
|
std::string GetId() { return fId; }
|
||||||
|
|
||||||
|
const tools::Version GetVersion() const { return fVersion; }
|
||||||
|
|
||||||
|
void SetNumIoThreads(int numIoThreads) { fConfig->SetProperty("io-threads", numIoThreads); }
|
||||||
|
int GetNumIoThreads() const
|
||||||
|
{
|
||||||
|
return fConfig->GetProperty<int>("io-threads", DefaultIOThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNetworkInterface(const std::string& networkInterface)
|
||||||
|
{
|
||||||
|
fConfig->SetProperty("network-interface", networkInterface);
|
||||||
|
}
|
||||||
|
std::string GetNetworkInterface() const
|
||||||
|
{
|
||||||
|
return fConfig->GetProperty<std::string>("network-interface", DefaultNetworkInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDefaultTransport(const std::string& name) { fConfig->SetProperty("transport", name); }
|
||||||
|
std::string GetDefaultTransport() const
|
||||||
|
{
|
||||||
|
return fConfig->GetProperty<std::string>("transport", DefaultTransportName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInitTimeoutInS(int initTimeoutInS)
|
||||||
|
{
|
||||||
|
fConfig->SetProperty("init-timeout", initTimeoutInS);
|
||||||
|
}
|
||||||
|
int GetInitTimeoutInS() const
|
||||||
|
{
|
||||||
|
return fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the default transport for the device
|
||||||
|
/// @param transport Transport string ("zeromq"/"shmem")
|
||||||
|
void SetTransport(const std::string& transport)
|
||||||
|
{
|
||||||
|
fConfig->SetProperty("transport", transport);
|
||||||
|
}
|
||||||
|
/// Gets the default transport name
|
||||||
|
std::string GetTransportName() const
|
||||||
|
{
|
||||||
|
return fConfig->GetProperty<std::string>("transport", DefaultTransportName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
||||||
|
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
||||||
|
|
||||||
|
void RunStateMachine() { fStateMachine.ProcessWork(); };
|
||||||
|
|
||||||
|
/// Wait for the supplied amount of time or for interruption.
|
||||||
|
/// If interrupted, returns false, otherwise true.
|
||||||
|
/// @param duration wait duration
|
||||||
|
template<typename Rep, typename Period>
|
||||||
|
bool WaitFor(std::chrono::duration<Rep, Period> const& duration)
|
||||||
|
{
|
||||||
|
return !fStateMachine.WaitForPendingStateFor(
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<TransportFactory> fTransportFactory; ///< Default transport factory
|
||||||
|
std::unordered_map<mq::Transport, std::shared_ptr<TransportFactory>>
|
||||||
|
fTransports; ///< Container for transports
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::unordered_map<std::string, std::vector<Channel>> fChannels; ///< Device channels
|
||||||
|
std::unique_ptr<ProgOptions> fInternalConfig; ///< Internal program options configuration
|
||||||
|
ProgOptions* fConfig; ///< Pointer to config (internal or external)
|
||||||
|
|
||||||
|
void AddChannel(const std::string& name, Channel&& channel)
|
||||||
|
{
|
||||||
|
fConfig->AddChannel(name, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string fId; ///< Device ID
|
||||||
|
|
||||||
|
/// Additional user initialization (can be overloaded in child classes). Prefer to use
|
||||||
|
/// InitTask().
|
||||||
|
virtual void Init() {}
|
||||||
|
|
||||||
|
virtual void Bind() {}
|
||||||
|
|
||||||
|
virtual void Connect() {}
|
||||||
|
|
||||||
|
/// Task initialization (can be overloaded in child classes)
|
||||||
|
virtual void InitTask() {}
|
||||||
|
|
||||||
|
/// Runs the device (to be overloaded in child classes)
|
||||||
|
virtual void Run() {}
|
||||||
|
|
||||||
|
/// Called in the RUNNING state once before executing the Run()/ConditionalRun() method
|
||||||
|
virtual void PreRun() {}
|
||||||
|
|
||||||
|
/// Called during RUNNING state repeatedly until it returns false or device state changes
|
||||||
|
virtual bool ConditionalRun() { return false; }
|
||||||
|
|
||||||
|
/// Called in the RUNNING state once after executing the Run()/ConditionalRun() method
|
||||||
|
virtual void PostRun() {}
|
||||||
|
|
||||||
|
/// Resets the user task (to be overloaded in child classes)
|
||||||
|
virtual void ResetTask() {}
|
||||||
|
|
||||||
|
/// Resets the device (can be overloaded in child classes)
|
||||||
|
virtual void Reset() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// @brief Request a device state transition
|
||||||
|
/// @param transition state transition
|
||||||
|
///
|
||||||
|
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||||
|
/// pending transition event and terminates. In other words, the device states are scheduled
|
||||||
|
/// cooperatively.
|
||||||
|
bool ChangeState(const Transition transition) { return fStateMachine.ChangeState(transition); }
|
||||||
|
/// @brief Request a device state transition
|
||||||
|
/// @param transition state transition
|
||||||
|
///
|
||||||
|
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||||
|
/// pending transition event and terminates. In other words, the device states are scheduled
|
||||||
|
/// cooperatively.
|
||||||
|
bool ChangeState(const std::string& transition)
|
||||||
|
{
|
||||||
|
return fStateMachine.ChangeState(GetTransition(transition));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief waits for the next state (any) to occur
|
||||||
|
State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
||||||
|
/// @brief waits for the specified state to occur
|
||||||
|
/// @param state state to wait for
|
||||||
|
void WaitForState(State state) { fStateQueue.WaitForState(state); }
|
||||||
|
/// @brief waits for the specified state to occur
|
||||||
|
/// @param state state to wait for
|
||||||
|
void WaitForState(const std::string& state) { WaitForState(GetState(state)); }
|
||||||
|
|
||||||
|
void TransitionTo(const State state);
|
||||||
|
|
||||||
|
/// @brief Subscribe with a callback to state changes
|
||||||
|
/// @param key id to identify your subscription
|
||||||
|
/// @param callback callback (called with the new state as the parameter)
|
||||||
|
///
|
||||||
|
/// The callback is called at the beginning of a new state.
|
||||||
|
/// The callback is called from the thread the state is running in.
|
||||||
|
void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback)
|
||||||
|
{
|
||||||
|
fStateMachine.SubscribeToStateChange(key, callback);
|
||||||
|
}
|
||||||
|
/// @brief Unsubscribe from state changes
|
||||||
|
/// @param key id (that was used when subscribing)
|
||||||
|
void UnsubscribeFromStateChange(const std::string& key)
|
||||||
|
{
|
||||||
|
fStateMachine.UnsubscribeFromStateChange(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Subscribe with a callback to incoming state transitions
|
||||||
|
/// @param key id to identify your subscription
|
||||||
|
/// @param callback callback (called with the incoming transition as the parameter)
|
||||||
|
/// The callback is called when new transition is initiated.
|
||||||
|
/// The callback is called from the thread that initiates the transition (via ChangeState).
|
||||||
|
void SubscribeToNewTransition(const std::string& key,
|
||||||
|
std::function<void(const Transition)> callback)
|
||||||
|
{
|
||||||
|
fStateMachine.SubscribeToNewTransition(key, callback);
|
||||||
|
}
|
||||||
|
/// @brief Unsubscribe from state transitions
|
||||||
|
/// @param key id (that was used when subscribing)
|
||||||
|
void UnsubscribeFromNewTransition(const std::string& key)
|
||||||
|
{
|
||||||
|
fStateMachine.UnsubscribeFromNewTransition(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns true if a new state has been requested, signaling the current handler to
|
||||||
|
/// stop.
|
||||||
|
bool NewStatePending() const { return fStateMachine.NewStatePending(); }
|
||||||
|
|
||||||
|
/// @brief Returns the current state
|
||||||
|
State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
||||||
|
/// @brief Returns the name of the current state as a string
|
||||||
|
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
||||||
|
|
||||||
|
/// @brief Returns name of the given state as a string
|
||||||
|
/// @param state state
|
||||||
|
static std::string GetStateName(const State state) { return GetStateName(state); }
|
||||||
|
/// @brief Returns name of the given transition as a string
|
||||||
|
/// @param transition transition
|
||||||
|
static std::string GetTransitionName(const Transition transition)
|
||||||
|
{
|
||||||
|
return GetTransitionName(transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr const char* DefaultId = "";
|
||||||
|
static constexpr int DefaultIOThreads = 1;
|
||||||
|
static constexpr const char* DefaultTransportName = "zeromq";
|
||||||
|
static constexpr mq::Transport DefaultTransportType = mq::Transport::ZMQ;
|
||||||
|
static constexpr const char* DefaultNetworkInterface = "default";
|
||||||
|
static constexpr int DefaultInitTimeout = 120;
|
||||||
|
static constexpr uint64_t DefaultMaxRunTime = 0;
|
||||||
|
static constexpr float DefaultRate = 0.;
|
||||||
|
static constexpr const char* DefaultSession = "default";
|
||||||
|
|
||||||
|
private:
|
||||||
|
mq::Transport fDefaultTransportType; ///< Default transport for the device
|
||||||
|
StateMachine fStateMachine;
|
||||||
|
|
||||||
|
/// Handles the initialization
|
||||||
|
void InitWrapper();
|
||||||
|
/// Initializes binding channels
|
||||||
|
void BindWrapper();
|
||||||
|
/// Initializes connecting channels
|
||||||
|
void ConnectWrapper();
|
||||||
|
/// Handles the InitTask() method
|
||||||
|
void InitTaskWrapper();
|
||||||
|
/// Handles the Run() method
|
||||||
|
void RunWrapper();
|
||||||
|
/// Handles the ResetTask() method
|
||||||
|
void ResetTaskWrapper();
|
||||||
|
/// Handles the Reset() method
|
||||||
|
void ResetWrapper();
|
||||||
|
|
||||||
|
/// Notifies transports to cease any blocking activity
|
||||||
|
void UnblockTransports();
|
||||||
|
|
||||||
|
/// Shuts down the transports and the device
|
||||||
|
void Exit() {}
|
||||||
|
|
||||||
|
/// Attach (bind/connect) channels in the list
|
||||||
|
void AttachChannels(std::vector<Channel*>& chans);
|
||||||
|
bool AttachChannel(Channel& ch);
|
||||||
|
|
||||||
|
void HandleSingleChannelInput();
|
||||||
|
void HandleMultipleChannelInput();
|
||||||
|
void HandleMultipleTransportInput();
|
||||||
|
void PollForTransport(const TransportFactory* factory,
|
||||||
|
const std::vector<std::string>& channelKeys);
|
||||||
|
|
||||||
|
bool HandleMsgInput(const std::string& chName, const InputMsgCallback& callback, int i);
|
||||||
|
bool HandleMultipartInput(const std::string& chName,
|
||||||
|
const InputMultipartCallback& callback,
|
||||||
|
int i);
|
||||||
|
|
||||||
|
std::vector<Channel*> fUninitializedBindingChannels;
|
||||||
|
std::vector<Channel*> fUninitializedConnectingChannels;
|
||||||
|
|
||||||
|
bool fDataCallbacks;
|
||||||
|
std::unordered_map<std::string, InputMsgCallback> fMsgInputs;
|
||||||
|
std::unordered_map<std::string, InputMultipartCallback> fMultipartInputs;
|
||||||
|
std::unordered_map<mq::Transport, std::vector<std::string>> fMultitransportInputs;
|
||||||
|
std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> fChannelRegistry;
|
||||||
|
std::vector<std::string> fInputChannelKeys;
|
||||||
|
std::mutex fMultitransportMutex;
|
||||||
|
std::atomic<bool> fMultitransportProceed;
|
||||||
|
|
||||||
|
const tools::Version fVersion;
|
||||||
|
float fRate; ///< Rate limiting for ConditionalRun
|
||||||
|
uint64_t fMaxRunRuntimeInS; ///< Maximum runtime for the Running state handler, after which
|
||||||
|
///< state will change to Ready (in seconds, 0 for no limit).
|
||||||
|
int fInitializationTimeoutInS;
|
||||||
|
std::vector<std::string> fRawCmdLineArgs;
|
||||||
|
|
||||||
|
StateQueue fStateQueue;
|
||||||
|
|
||||||
|
std::mutex fTransitionMtx;
|
||||||
|
bool fTransitioning;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQChannelMap [[deprecated("Use fair::mq::ChannelMap")]] = fair::mq::ChannelMap;
|
||||||
|
// using InputMsgCallback [[deprecated("Use fair::mq::InputMsgCallback")]] =
|
||||||
|
// fair::mq::InputMsgCallback;
|
||||||
|
// using InputMultipartCallback [[deprecated("Use fair::mq::InputMultipartCallback")]] =
|
||||||
|
// fair::mq::InputMultipartCallback;
|
||||||
|
// using FairMQDevice [[deprecated("Use fair::mq::Device")]] = fair::mq::Device;
|
||||||
|
using FairMQChannelMap = fair::mq::ChannelMap;
|
||||||
|
using InputMsgCallback = fair::mq::InputMsgCallback;
|
||||||
|
using InputMultipartCallback = fair::mq::InputMultipartCallback;
|
||||||
|
using FairMQDevice = fair::mq::Device;
|
||||||
|
|
||||||
#endif /* FAIR_MQ_DEVICE_H */
|
#endif /* FAIR_MQ_DEVICE_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,442 +9,12 @@
|
||||||
#ifndef FAIRMQCHANNEL_H_
|
#ifndef FAIRMQCHANNEL_H_
|
||||||
#define FAIRMQCHANNEL_H_
|
#define FAIRMQCHANNEL_H_
|
||||||
|
|
||||||
#include <FairMQTransportFactory.h>
|
#if 0
|
||||||
#include <FairMQUnmanagedRegion.h>
|
#ifndef FAIR_MQ_CHANNEL_H
|
||||||
#include <FairMQSocket.h>
|
#pragma GCC warning "Deprecated header: Use <fairmq/Channel.h> instead"
|
||||||
#include <fairmq/Transports.h>
|
#endif
|
||||||
#include <FairMQParts.h>
|
#endif
|
||||||
#include <fairmq/Properties.h>
|
|
||||||
#include <FairMQMessage.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <fairmq/Channel.h>
|
||||||
#include <memory> // unique_ptr, shared_ptr
|
|
||||||
#include <vector>
|
|
||||||
#include <mutex>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility> // std::move
|
|
||||||
#include <cstdint> // int64_t
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class FairMQChannel FairMQChannel.h <FairMQChannel.h>
|
|
||||||
* @brief Wrapper class for FairMQSocket and related methods
|
|
||||||
*
|
|
||||||
* The class is not thread-safe.
|
|
||||||
*/
|
|
||||||
class FairMQChannel
|
|
||||||
{
|
|
||||||
friend class FairMQDevice;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Default constructor
|
|
||||||
FairMQChannel();
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param name Channel name
|
|
||||||
FairMQChannel(const std::string& name);
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
|
||||||
/// @param method Socket method (bind/connect)
|
|
||||||
/// @param address Network address to bind/connect to (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
|
||||||
FairMQChannel(const std::string& type, const std::string& method, const std::string& address);
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param name Channel name
|
|
||||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
|
||||||
/// @param factory TransportFactory
|
|
||||||
FairMQChannel(const std::string& name, const std::string& type, std::shared_ptr<FairMQTransportFactory> factory);
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
/// @param name Channel name
|
|
||||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
|
||||||
/// @param method Socket method (bind/connect)
|
|
||||||
/// @param address Network address to bind/connect to (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
|
||||||
/// @param factory TransportFactory
|
|
||||||
FairMQChannel(std::string name, std::string type, std::string method, std::string address, std::shared_ptr<FairMQTransportFactory> factory);
|
|
||||||
|
|
||||||
FairMQChannel(const std::string& name, int index, const fair::mq::Properties& properties);
|
|
||||||
|
|
||||||
/// Copy Constructor
|
|
||||||
FairMQChannel(const FairMQChannel&);
|
|
||||||
|
|
||||||
/// Copy Constructor (with new name)
|
|
||||||
FairMQChannel(const FairMQChannel&, std::string name);
|
|
||||||
|
|
||||||
/// Move constructor
|
|
||||||
// FairMQChannel(FairMQChannel&&) = delete;
|
|
||||||
|
|
||||||
/// Assignment operator
|
|
||||||
FairMQChannel& operator=(const FairMQChannel&);
|
|
||||||
|
|
||||||
/// Move assignment operator
|
|
||||||
// FairMQChannel& operator=(FairMQChannel&&) = delete;
|
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
virtual ~FairMQChannel() = default;
|
|
||||||
// { LOG(warn) << "Destroying channel '" << fName << "'"; }
|
|
||||||
|
|
||||||
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
FairMQSocket& GetSocket() const { assert(fSocket); return *fSocket; }
|
|
||||||
|
|
||||||
bool Bind(const std::string& address)
|
|
||||||
{
|
|
||||||
fMethod = "bind";
|
|
||||||
fAddress = address;
|
|
||||||
return fSocket->Bind(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Connect(const std::string& address)
|
|
||||||
{
|
|
||||||
fMethod = "connect";
|
|
||||||
fAddress = address;
|
|
||||||
return fSocket->Connect(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get channel name
|
|
||||||
/// @return Returns full channel name (e.g. "data[0]")
|
|
||||||
std::string GetName() const { return fName; }
|
|
||||||
|
|
||||||
/// Get channel prefix
|
|
||||||
/// @return Returns channel prefix (e.g. "data" in "data[0]")
|
|
||||||
std::string GetPrefix() const
|
|
||||||
{
|
|
||||||
std::string prefix = fName;
|
|
||||||
prefix = prefix.erase(fName.rfind('['));
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get channel index
|
|
||||||
/// @return Returns channel index (e.g. 0 in "data[0]")
|
|
||||||
std::string GetIndex() const
|
|
||||||
{
|
|
||||||
std::string indexStr = fName;
|
|
||||||
indexStr.erase(indexStr.rfind(']'));
|
|
||||||
indexStr.erase(0, indexStr.rfind('[') + 1);
|
|
||||||
return indexStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get socket type
|
|
||||||
/// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
|
||||||
std::string GetType() const { return fType; }
|
|
||||||
|
|
||||||
/// Get socket method
|
|
||||||
/// @return Returns socket method (bind/connect)
|
|
||||||
std::string GetMethod() const { return fMethod; }
|
|
||||||
|
|
||||||
/// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
|
||||||
/// @return Returns socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
|
||||||
std::string GetAddress() const { return fAddress; }
|
|
||||||
|
|
||||||
/// Get channel transport name ("default", "zeromq" or "shmem")
|
|
||||||
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
|
|
||||||
std::string GetTransportName() const { return fair::mq::TransportName(fTransportType); }
|
|
||||||
|
|
||||||
/// Get channel transport type
|
|
||||||
/// @return Returns channel transport type
|
|
||||||
fair::mq::Transport GetTransportType() const { return fTransportType; }
|
|
||||||
|
|
||||||
/// Get socket send buffer size (in number of messages)
|
|
||||||
/// @return Returns socket send buffer size (in number of messages)
|
|
||||||
int GetSndBufSize() const { return fSndBufSize; }
|
|
||||||
|
|
||||||
/// Get socket receive buffer size (in number of messages)
|
|
||||||
/// @return Returns socket receive buffer size (in number of messages)
|
|
||||||
int GetRcvBufSize() const { return fRcvBufSize; }
|
|
||||||
|
|
||||||
/// Get socket kernel transmit send buffer size (in bytes)
|
|
||||||
/// @return Returns socket kernel transmit send buffer size (in bytes)
|
|
||||||
int GetSndKernelSize() const { return fSndKernelSize; }
|
|
||||||
|
|
||||||
/// Get socket kernel transmit receive buffer size (in bytes)
|
|
||||||
/// @return Returns socket kernel transmit receive buffer size (in bytes)
|
|
||||||
int GetRcvKernelSize() const { return fRcvKernelSize; }
|
|
||||||
|
|
||||||
/// Get linger duration (in milliseconds)
|
|
||||||
/// @return Returns linger duration (in milliseconds)
|
|
||||||
int GetLinger() const { return fLinger; }
|
|
||||||
|
|
||||||
/// Get socket rate logging interval (in seconds)
|
|
||||||
/// @return Returns socket rate logging interval (in seconds)
|
|
||||||
int GetRateLogging() const { return fRateLogging; }
|
|
||||||
|
|
||||||
/// Get start of the port range for automatic binding
|
|
||||||
/// @return start of the port range
|
|
||||||
int GetPortRangeMin() const { return fPortRangeMin; }
|
|
||||||
|
|
||||||
/// Get end of the port range for automatic binding
|
|
||||||
/// @return end of the port range
|
|
||||||
int GetPortRangeMax() const { return fPortRangeMax; }
|
|
||||||
|
|
||||||
/// Set automatic binding (pick random port if bind fails)
|
|
||||||
/// @return true/false, true if automatic binding is enabled
|
|
||||||
bool GetAutoBind() const { return fAutoBind; }
|
|
||||||
|
|
||||||
/// Set channel name
|
|
||||||
/// @param name Arbitrary channel name
|
|
||||||
void UpdateName(const std::string& name) { fName = name; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket type
|
|
||||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
|
||||||
void UpdateType(const std::string& type) { fType = type; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket method
|
|
||||||
/// @param method Socket method (bind/connect)
|
|
||||||
void UpdateMethod(const std::string& method) { fMethod = method; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket address
|
|
||||||
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
|
||||||
void UpdateAddress(const std::string& address) { fAddress = address; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set channel transport
|
|
||||||
/// @param transport transport string ("default", "zeromq" or "shmem")
|
|
||||||
void UpdateTransport(const std::string& transport) { fTransportType = fair::mq::TransportType(transport); Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket send buffer size
|
|
||||||
/// @param sndBufSize Socket send buffer size (in number of messages)
|
|
||||||
void UpdateSndBufSize(const int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket receive buffer size
|
|
||||||
/// @param rcvBufSize Socket receive buffer size (in number of messages)
|
|
||||||
void UpdateRcvBufSize(const int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket kernel transmit send buffer size (in bytes)
|
|
||||||
/// @param sndKernelSize Socket send buffer size (in bytes)
|
|
||||||
void UpdateSndKernelSize(const int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket kernel transmit receive buffer size (in bytes)
|
|
||||||
/// @param rcvKernelSize Socket receive buffer size (in bytes)
|
|
||||||
void UpdateRcvKernelSize(const int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set linger duration (in milliseconds)
|
|
||||||
/// @param duration linger duration (in milliseconds)
|
|
||||||
void UpdateLinger(const int duration) { fLinger = duration; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set socket rate logging interval (in seconds)
|
|
||||||
/// @param rateLogging Socket rate logging interval (in seconds)
|
|
||||||
void UpdateRateLogging(const int rateLogging) { fRateLogging = rateLogging; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set start of the port range for automatic binding
|
|
||||||
/// @param minPort start of the port range
|
|
||||||
void UpdatePortRangeMin(const int minPort) { fPortRangeMin = minPort; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set end of the port range for automatic binding
|
|
||||||
/// @param maxPort end of the port range
|
|
||||||
void UpdatePortRangeMax(const int maxPort) { fPortRangeMax = maxPort; Invalidate(); }
|
|
||||||
|
|
||||||
/// Set automatic binding (pick random port if bind fails)
|
|
||||||
/// @param autobind true/false, true to enable automatic binding
|
|
||||||
void UpdateAutoBind(const bool autobind) { fAutoBind = autobind; Invalidate(); }
|
|
||||||
|
|
||||||
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
|
|
||||||
/// @return true if channel settings are valid, false otherwise.
|
|
||||||
bool IsValid() const { return fValid; }
|
|
||||||
|
|
||||||
/// Validates channel configuration
|
|
||||||
/// @return true if channel settings are valid, false otherwise.
|
|
||||||
bool Validate();
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
bool ConnectEndpoint(const std::string& endpoint);
|
|
||||||
|
|
||||||
bool BindEndpoint(std::string& endpoint);
|
|
||||||
|
|
||||||
/// invalidates the channel (requires validation to be used again).
|
|
||||||
void Invalidate() { fValid = false; }
|
|
||||||
|
|
||||||
/// Sends a message to the socket queue.
|
|
||||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
|
||||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
|
||||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Send(FairMQMessagePtr& msg, int sndTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
CheckSendCompatibility(msg);
|
|
||||||
return fSocket->Send(msg, sndTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receives a message from the socket queue.
|
|
||||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
|
||||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
|
||||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
CheckReceiveCompatibility(msg);
|
|
||||||
return fSocket->Receive(msg, rcvTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Send a vector of messages
|
|
||||||
/// @param msgVec message vector reference
|
|
||||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
|
||||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Send(std::vector<FairMQMessagePtr>& msgVec, int sndTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
CheckSendCompatibility(msgVec);
|
|
||||||
return fSocket->Send(msgVec, sndTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receive a vector of messages
|
|
||||||
/// @param msgVec message vector reference
|
|
||||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
|
||||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Receive(std::vector<FairMQMessagePtr>& msgVec, int rcvTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
CheckReceiveCompatibility(msgVec);
|
|
||||||
return fSocket->Receive(msgVec, rcvTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Send FairMQParts
|
|
||||||
/// @param parts FairMQParts reference
|
|
||||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
|
||||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Send(FairMQParts& parts, int sndTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return Send(parts.fParts, sndTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receive FairMQParts
|
|
||||||
/// @param parts FairMQParts reference
|
|
||||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
|
||||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Receive(FairMQParts& parts, int rcvTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return Receive(parts.fParts, rcvTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long GetBytesTx() const { return fSocket->GetBytesTx(); }
|
|
||||||
unsigned long GetBytesRx() const { return fSocket->GetBytesRx(); }
|
|
||||||
unsigned long GetMessagesTx() const { return fSocket->GetMessagesTx(); }
|
|
||||||
unsigned long GetMessagesRx() const { return fSocket->GetMessagesRx(); }
|
|
||||||
|
|
||||||
auto Transport() -> FairMQTransportFactory* { return fTransportFactory.get(); };
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQMessagePtr NewMessage(Args&&... args)
|
|
||||||
{
|
|
||||||
return Transport()->CreateMessage(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewSimpleMessage(const T& data)
|
|
||||||
{
|
|
||||||
return Transport()->NewSimpleMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewStaticMessage(const T& data)
|
|
||||||
{
|
|
||||||
return Transport()->NewStaticMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
|
||||||
{
|
|
||||||
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::DEFAULT;
|
|
||||||
static constexpr const char* DefaultTransportName = "default";
|
|
||||||
static constexpr const char* DefaultName = "";
|
|
||||||
static constexpr const char* DefaultType = "unspecified";
|
|
||||||
static constexpr const char* DefaultMethod = "unspecified";
|
|
||||||
static constexpr const char* DefaultAddress = "unspecified";
|
|
||||||
static constexpr int DefaultSndBufSize = 1000;
|
|
||||||
static constexpr int DefaultRcvBufSize = 1000;
|
|
||||||
static constexpr int DefaultSndKernelSize = 0;
|
|
||||||
static constexpr int DefaultRcvKernelSize = 0;
|
|
||||||
static constexpr int DefaultLinger = 500;
|
|
||||||
static constexpr int DefaultRateLogging = 1;
|
|
||||||
static constexpr int DefaultPortRangeMin = 22000;
|
|
||||||
static constexpr int DefaultPortRangeMax = 23000;
|
|
||||||
static constexpr bool DefaultAutoBind = true;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory;
|
|
||||||
fair::mq::Transport fTransportType;
|
|
||||||
std::unique_ptr<FairMQSocket> fSocket;
|
|
||||||
|
|
||||||
std::string fName;
|
|
||||||
std::string fType;
|
|
||||||
std::string fMethod;
|
|
||||||
std::string fAddress;
|
|
||||||
int fSndBufSize;
|
|
||||||
int fRcvBufSize;
|
|
||||||
int fSndKernelSize;
|
|
||||||
int fRcvKernelSize;
|
|
||||||
int fLinger;
|
|
||||||
int fRateLogging;
|
|
||||||
int fPortRangeMin;
|
|
||||||
int fPortRangeMax;
|
|
||||||
bool fAutoBind;
|
|
||||||
|
|
||||||
bool fValid;
|
|
||||||
|
|
||||||
bool fMultipart;
|
|
||||||
|
|
||||||
void CheckSendCompatibility(FairMQMessagePtr& msg)
|
|
||||||
{
|
|
||||||
if (fTransportType != msg->GetType()) {
|
|
||||||
if (msg->GetSize() > 0) {
|
|
||||||
FairMQMessagePtr msgWrapper(NewMessage(
|
|
||||||
msg->GetData(),
|
|
||||||
msg->GetSize(),
|
|
||||||
[](void* /*data*/, void* _msg) { delete static_cast<FairMQMessage*>(_msg); },
|
|
||||||
msg.get()
|
|
||||||
));
|
|
||||||
msg.release();
|
|
||||||
msg = move(msgWrapper);
|
|
||||||
} else {
|
|
||||||
FairMQMessagePtr newMsg(NewMessage());
|
|
||||||
msg = move(newMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckSendCompatibility(std::vector<FairMQMessagePtr>& msgVec)
|
|
||||||
{
|
|
||||||
for (auto& msg : msgVec) {
|
|
||||||
if (fTransportType != msg->GetType()) {
|
|
||||||
if (msg->GetSize() > 0) {
|
|
||||||
FairMQMessagePtr msgWrapper(NewMessage(
|
|
||||||
msg->GetData(),
|
|
||||||
msg->GetSize(),
|
|
||||||
[](void* /*data*/, void* _msg) { delete static_cast<FairMQMessage*>(_msg); },
|
|
||||||
msg.get()
|
|
||||||
));
|
|
||||||
msg.release();
|
|
||||||
msg = move(msgWrapper);
|
|
||||||
} else {
|
|
||||||
FairMQMessagePtr newMsg(NewMessage());
|
|
||||||
msg = move(newMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckReceiveCompatibility(FairMQMessagePtr& msg)
|
|
||||||
{
|
|
||||||
if (fTransportType != msg->GetType()) {
|
|
||||||
FairMQMessagePtr newMsg(NewMessage());
|
|
||||||
msg = move(newMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckReceiveCompatibility(std::vector<FairMQMessagePtr>& msgVec)
|
|
||||||
{
|
|
||||||
for (auto& msg : msgVec) {
|
|
||||||
if (fTransportType != msg->GetType()) {
|
|
||||||
FairMQMessagePtr newMsg(NewMessage());
|
|
||||||
msg = move(newMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitTransport(std::shared_ptr<FairMQTransportFactory> factory)
|
|
||||||
{
|
|
||||||
fTransportFactory = factory;
|
|
||||||
fTransportType = factory->GetType();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FAIRMQCHANNEL_H_ */
|
#endif /* FAIRMQCHANNEL_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2012-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,545 +9,12 @@
|
||||||
#ifndef FAIRMQDEVICE_H_
|
#ifndef FAIRMQDEVICE_H_
|
||||||
#define FAIRMQDEVICE_H_
|
#define FAIRMQDEVICE_H_
|
||||||
|
|
||||||
#include <FairMQChannel.h>
|
#if 0
|
||||||
#include <FairMQLogger.h>
|
#ifndef FAIR_MQ_DEVICE_H
|
||||||
#include <FairMQMessage.h>
|
#pragma GCC warning "Deprecated header: Use <fairmq/Device.h> instead"
|
||||||
#include <FairMQParts.h>
|
#endif
|
||||||
#include <FairMQTransportFactory.h>
|
#endif
|
||||||
#include <FairMQUnmanagedRegion.h>
|
|
||||||
#include <fairmq/ProgOptions.h>
|
|
||||||
#include <fairmq/StateMachine.h>
|
|
||||||
#include <fairmq/StateQueue.h>
|
|
||||||
#include <fairmq/Transports.h>
|
|
||||||
#include <fairmq/tools/Version.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <fairmq/Device.h>
|
||||||
#include <memory> // unique_ptr
|
|
||||||
#include <algorithm> // find
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <functional>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <mutex>
|
|
||||||
#include <atomic>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <utility> // pair
|
|
||||||
|
|
||||||
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
|
||||||
|
|
||||||
using InputMsgCallback = std::function<bool(FairMQMessagePtr&, int)>;
|
|
||||||
using InputMultipartCallback = std::function<bool(FairMQParts&, int)>;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
struct OngoingTransition : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
}
|
|
||||||
|
|
||||||
class FairMQDevice
|
|
||||||
{
|
|
||||||
friend class FairMQChannel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Default constructor
|
|
||||||
FairMQDevice();
|
|
||||||
/// Constructor with external fair::mq::ProgOptions
|
|
||||||
FairMQDevice(fair::mq::ProgOptions& config);
|
|
||||||
|
|
||||||
/// Constructor that sets the version
|
|
||||||
FairMQDevice(const fair::mq::tools::Version version);
|
|
||||||
|
|
||||||
/// Constructor that sets the version and external fair::mq::ProgOptions
|
|
||||||
FairMQDevice(fair::mq::ProgOptions& config, const fair::mq::tools::Version version);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FairMQDevice(fair::mq::ProgOptions* config, const fair::mq::tools::Version version);
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Copy constructor (disabled)
|
|
||||||
FairMQDevice(const FairMQDevice&) = delete;
|
|
||||||
/// Assignment operator (disabled)
|
|
||||||
FairMQDevice operator=(const FairMQDevice&) = delete;
|
|
||||||
/// Default destructor
|
|
||||||
virtual ~FairMQDevice();
|
|
||||||
|
|
||||||
/// Outputs the socket transfer rates
|
|
||||||
virtual void LogSocketRates();
|
|
||||||
|
|
||||||
template<typename Serializer, typename DataType, typename... Args>
|
|
||||||
void Serialize(FairMQMessage& msg, DataType&& data, Args&&... args) const
|
|
||||||
{
|
|
||||||
Serializer().Serialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Deserializer, typename DataType, typename... Args>
|
|
||||||
void Deserialize(FairMQMessage& msg, DataType&& data, Args&&... args) const
|
|
||||||
{
|
|
||||||
Deserializer().Deserialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shorthand method to send `msg` on `chan` at index `i`
|
|
||||||
/// @param msg message reference
|
|
||||||
/// @param chan channel name
|
|
||||||
/// @param i channel index
|
|
||||||
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
|
||||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Send(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).Send(msg, sndTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shorthand method to receive `msg` on `chan` at index `i`
|
|
||||||
/// @param msg message reference
|
|
||||||
/// @param chan channel name
|
|
||||||
/// @param i channel index
|
|
||||||
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
|
||||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Receive(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shorthand method to send FairMQParts on `chan` at index `i`
|
|
||||||
/// @param parts parts reference
|
|
||||||
/// @param chan channel name
|
|
||||||
/// @param i channel index
|
|
||||||
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
|
||||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Send(FairMQParts& parts, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).Send(parts.fParts, sndTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shorthand method to receive FairMQParts on `chan` at index `i`
|
|
||||||
/// @param parts parts reference
|
|
||||||
/// @param chan channel name
|
|
||||||
/// @param i channel index
|
|
||||||
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
|
||||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
|
||||||
int64_t Receive(FairMQParts& parts, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Getter for default transport factory
|
|
||||||
auto Transport() const -> FairMQTransportFactory*
|
|
||||||
{
|
|
||||||
return fTransportFactory.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates message with the default device transport
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQMessagePtr NewMessage(Args&&... args)
|
|
||||||
{
|
|
||||||
return Transport()->CreateMessage(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates message with the transport of the specified channel
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQMessagePtr NewMessageFor(const std::string& channel, int index, Args&&... args)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).NewMessage(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a message that will not be cleaned up after transfer, with the default device transport
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewStaticMessage(const T& data)
|
|
||||||
{
|
|
||||||
return Transport()->NewStaticMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a message that will not be cleaned up after transfer, with the transport of the specified channel
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewStaticMessageFor(const std::string& channel, int index, const T& data)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).NewStaticMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a message with a copy of the provided data, with the default device transport
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewSimpleMessage(const T& data)
|
|
||||||
{
|
|
||||||
return Transport()->NewSimpleMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a message with a copy of the provided data, with the transport of the specified channel
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewSimpleMessageFor(const std::string& channel, int index, const T& data)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).NewSimpleMessage(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates unamanaged region with the default device transport
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
|
||||||
{
|
|
||||||
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates unmanaged region with the transport of the specified channel
|
|
||||||
template<typename... Args>
|
|
||||||
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, Args&&... args)
|
|
||||||
{
|
|
||||||
return GetChannel(channel, index).NewUnmanagedRegion(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...Ts>
|
|
||||||
FairMQPollerPtr NewPoller(const Ts&... inputs)
|
|
||||||
{
|
|
||||||
std::vector<std::string> chans{inputs...};
|
|
||||||
|
|
||||||
// if more than one channel provided, check compatibility
|
|
||||||
if (chans.size() > 1)
|
|
||||||
{
|
|
||||||
fair::mq::Transport type = GetChannel(chans.at(0), 0).Transport()->GetType();
|
|
||||||
|
|
||||||
for (unsigned int i = 1; i < chans.size(); ++i)
|
|
||||||
{
|
|
||||||
if (type != GetChannel(chans.at(i), 0).Transport()->GetType())
|
|
||||||
{
|
|
||||||
LOG(error) << "poller failed: different transports within same poller are not yet supported. Going to ERROR state.";
|
|
||||||
throw std::runtime_error("poller failed: different transports within same poller are not yet supported.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetChannel(chans.at(0), 0).Transport()->CreatePoller(fChannels, chans);
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQPollerPtr NewPoller(const std::vector<FairMQChannel*>& channels)
|
|
||||||
{
|
|
||||||
// if more than one channel provided, check compatibility
|
|
||||||
if (channels.size() > 1)
|
|
||||||
{
|
|
||||||
fair::mq::Transport type = channels.at(0)->Transport()->GetType();
|
|
||||||
|
|
||||||
for (unsigned int i = 1; i < channels.size(); ++i)
|
|
||||||
{
|
|
||||||
if (type != channels.at(i)->Transport()->GetType())
|
|
||||||
{
|
|
||||||
LOG(error) << "poller failed: different transports within same poller are not yet supported. Going to ERROR state.";
|
|
||||||
throw std::runtime_error("poller failed: different transports within same poller are not yet supported.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return channels.at(0)->Transport()->CreatePoller(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a transport to the device if it doesn't exist
|
|
||||||
/// @param transport Transport string ("zeromq"/"shmem")
|
|
||||||
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
|
|
||||||
|
|
||||||
/// Assigns config to the device
|
|
||||||
void SetConfig(fair::mq::ProgOptions& config);
|
|
||||||
/// Get pointer to the config
|
|
||||||
fair::mq::ProgOptions* GetConfig() const
|
|
||||||
{
|
|
||||||
return fConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// overload to easily bind member functions
|
|
||||||
template<typename T>
|
|
||||||
void OnData(const std::string& channelName, bool (T::* memberFunction)(FairMQMessagePtr& msg, int index))
|
|
||||||
{
|
|
||||||
fDataCallbacks = true;
|
|
||||||
fMsgInputs.insert(std::make_pair(channelName, [this, memberFunction](FairMQMessagePtr& msg, int index)
|
|
||||||
{
|
|
||||||
return (static_cast<T*>(this)->*memberFunction)(msg, index);
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
|
|
||||||
{
|
|
||||||
fInputChannelKeys.push_back(channelName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnData(const std::string& channelName, InputMsgCallback callback)
|
|
||||||
{
|
|
||||||
fDataCallbacks = true;
|
|
||||||
fMsgInputs.insert(make_pair(channelName, callback));
|
|
||||||
|
|
||||||
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
|
|
||||||
{
|
|
||||||
fInputChannelKeys.push_back(channelName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// overload to easily bind member functions
|
|
||||||
template<typename T>
|
|
||||||
void OnData(const std::string& channelName, bool (T::* memberFunction)(FairMQParts& parts, int index))
|
|
||||||
{
|
|
||||||
fDataCallbacks = true;
|
|
||||||
fMultipartInputs.insert(std::make_pair(channelName, [this, memberFunction](FairMQParts& parts, int index)
|
|
||||||
{
|
|
||||||
return (static_cast<T*>(this)->*memberFunction)(parts, index);
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
|
|
||||||
{
|
|
||||||
fInputChannelKeys.push_back(channelName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnData(const std::string& channelName, InputMultipartCallback callback)
|
|
||||||
{
|
|
||||||
fDataCallbacks = true;
|
|
||||||
fMultipartInputs.insert(make_pair(channelName, callback));
|
|
||||||
|
|
||||||
if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
|
|
||||||
{
|
|
||||||
fInputChannelKeys.push_back(channelName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQChannel& GetChannel(const std::string& channelName, const int index = 0)
|
|
||||||
try {
|
|
||||||
return fChannels.at(channelName).at(index);
|
|
||||||
} catch (const std::out_of_range& oor) {
|
|
||||||
LOG(error) << "requested channel has not been configured? check channel names/configuration.";
|
|
||||||
LOG(error) << "channel: " << channelName << ", index: " << index;
|
|
||||||
LOG(error) << "out of range: " << oor.what();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void RegisterChannelEndpoints() {}
|
|
||||||
|
|
||||||
bool RegisterChannelEndpoint(const std::string& channelName, uint16_t minNumSubChannels = 1, uint16_t maxNumSubChannels = 1)
|
|
||||||
{
|
|
||||||
bool ok = fChannelRegistry.insert(std::make_pair(channelName, std::make_pair(minNumSubChannels, maxNumSubChannels))).second;
|
|
||||||
if (!ok) {
|
|
||||||
LOG(warn) << "Registering channel: name already registered: \"" << channelName << "\"";
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintRegisteredChannels()
|
|
||||||
{
|
|
||||||
if (fChannelRegistry.empty()) {
|
|
||||||
LOGV(info, verylow) << "no channels registered.";
|
|
||||||
} else {
|
|
||||||
for (const auto& c : fChannelRegistry) {
|
|
||||||
LOGV(info, verylow) << c.first << ":" << c.second.first << ":" << c.second.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetId(const std::string& id) { fId = id; }
|
|
||||||
std::string GetId() { return fId; }
|
|
||||||
|
|
||||||
const fair::mq::tools::Version GetVersion() const { return fVersion; }
|
|
||||||
|
|
||||||
void SetNumIoThreads(int numIoThreads) { fConfig->SetProperty("io-threads", numIoThreads);}
|
|
||||||
int GetNumIoThreads() const { return fConfig->GetProperty<int>("io-threads", DefaultIOThreads); }
|
|
||||||
|
|
||||||
void SetNetworkInterface(const std::string& networkInterface) { fConfig->SetProperty("network-interface", networkInterface); }
|
|
||||||
std::string GetNetworkInterface() const { return fConfig->GetProperty<std::string>("network-interface", DefaultNetworkInterface); }
|
|
||||||
|
|
||||||
void SetDefaultTransport(const std::string& name) { fConfig->SetProperty("transport", name); }
|
|
||||||
std::string GetDefaultTransport() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
|
|
||||||
|
|
||||||
void SetInitTimeoutInS(int initTimeoutInS) { fConfig->SetProperty("init-timeout", initTimeoutInS); }
|
|
||||||
int GetInitTimeoutInS() const { return fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout); }
|
|
||||||
|
|
||||||
/// Sets the default transport for the device
|
|
||||||
/// @param transport Transport string ("zeromq"/"shmem")
|
|
||||||
void SetTransport(const std::string& transport) { fConfig->SetProperty("transport", transport); }
|
|
||||||
/// Gets the default transport name
|
|
||||||
std::string GetTransportName() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
|
|
||||||
|
|
||||||
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
|
||||||
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
|
||||||
|
|
||||||
void RunStateMachine()
|
|
||||||
{
|
|
||||||
fStateMachine.ProcessWork();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Wait for the supplied amount of time or for interruption.
|
|
||||||
/// If interrupted, returns false, otherwise true.
|
|
||||||
/// @param duration wait duration
|
|
||||||
template<typename Rep, typename Period>
|
|
||||||
bool WaitFor(std::chrono::duration<Rep, Period> const& duration)
|
|
||||||
{
|
|
||||||
return !fStateMachine.WaitForPendingStateFor(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory; ///< Default transport factory
|
|
||||||
std::unordered_map<fair::mq::Transport, std::shared_ptr<FairMQTransportFactory>> fTransports; ///< Container for transports
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::unordered_map<std::string, std::vector<FairMQChannel>> fChannels; ///< Device channels
|
|
||||||
std::unique_ptr<fair::mq::ProgOptions> fInternalConfig; ///< Internal program options configuration
|
|
||||||
fair::mq::ProgOptions* fConfig; ///< Pointer to config (internal or external)
|
|
||||||
|
|
||||||
void AddChannel(const std::string& name, FairMQChannel&& channel)
|
|
||||||
{
|
|
||||||
fConfig->AddChannel(name, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string fId; ///< Device ID
|
|
||||||
|
|
||||||
/// Additional user initialization (can be overloaded in child classes). Prefer to use InitTask().
|
|
||||||
virtual void Init() {}
|
|
||||||
|
|
||||||
virtual void Bind() {}
|
|
||||||
|
|
||||||
virtual void Connect() {}
|
|
||||||
|
|
||||||
/// Task initialization (can be overloaded in child classes)
|
|
||||||
virtual void InitTask() {}
|
|
||||||
|
|
||||||
/// Runs the device (to be overloaded in child classes)
|
|
||||||
virtual void Run() {}
|
|
||||||
|
|
||||||
/// Called in the RUNNING state once before executing the Run()/ConditionalRun() method
|
|
||||||
virtual void PreRun() {}
|
|
||||||
|
|
||||||
/// Called during RUNNING state repeatedly until it returns false or device state changes
|
|
||||||
virtual bool ConditionalRun() { return false; }
|
|
||||||
|
|
||||||
/// Called in the RUNNING state once after executing the Run()/ConditionalRun() method
|
|
||||||
virtual void PostRun() {}
|
|
||||||
|
|
||||||
/// Resets the user task (to be overloaded in child classes)
|
|
||||||
virtual void ResetTask() {}
|
|
||||||
|
|
||||||
/// Resets the device (can be overloaded in child classes)
|
|
||||||
virtual void Reset() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// @brief Request a device state transition
|
|
||||||
/// @param transition state transition
|
|
||||||
///
|
|
||||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
|
||||||
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
|
|
||||||
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
|
|
||||||
/// @brief Request a device state transition
|
|
||||||
/// @param transition state transition
|
|
||||||
///
|
|
||||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
|
||||||
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
|
|
||||||
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::GetTransition(transition)); }
|
|
||||||
|
|
||||||
/// @brief waits for the next state (any) to occur
|
|
||||||
fair::mq::State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
|
||||||
/// @brief waits for the specified state to occur
|
|
||||||
/// @param state state to wait for
|
|
||||||
void WaitForState(fair::mq::State state) { fStateQueue.WaitForState(state); }
|
|
||||||
/// @brief waits for the specified state to occur
|
|
||||||
/// @param state state to wait for
|
|
||||||
void WaitForState(const std::string& state) { WaitForState(fair::mq::GetState(state)); }
|
|
||||||
|
|
||||||
void TransitionTo(const fair::mq::State state);
|
|
||||||
|
|
||||||
/// @brief Subscribe with a callback to state changes
|
|
||||||
/// @param key id to identify your subscription
|
|
||||||
/// @param callback callback (called with the new state as the parameter)
|
|
||||||
///
|
|
||||||
/// The callback is called at the beginning of a new state.
|
|
||||||
/// The callback is called from the thread the state is running in.
|
|
||||||
void SubscribeToStateChange(const std::string& key, std::function<void(const fair::mq::State)> callback) { fStateMachine.SubscribeToStateChange(key, callback); }
|
|
||||||
/// @brief Unsubscribe from state changes
|
|
||||||
/// @param key id (that was used when subscribing)
|
|
||||||
void UnsubscribeFromStateChange(const std::string& key) { fStateMachine.UnsubscribeFromStateChange(key); }
|
|
||||||
|
|
||||||
/// @brief Subscribe with a callback to incoming state transitions
|
|
||||||
/// @param key id to identify your subscription
|
|
||||||
/// @param callback callback (called with the incoming transition as the parameter)
|
|
||||||
/// The callback is called when new transition is initiated.
|
|
||||||
/// The callback is called from the thread that initiates the transition (via ChangeState).
|
|
||||||
void SubscribeToNewTransition(const std::string& key, std::function<void(const fair::mq::Transition)> callback) { fStateMachine.SubscribeToNewTransition(key, callback); }
|
|
||||||
/// @brief Unsubscribe from state transitions
|
|
||||||
/// @param key id (that was used when subscribing)
|
|
||||||
void UnsubscribeFromNewTransition(const std::string& key) { fStateMachine.UnsubscribeFromNewTransition(key); }
|
|
||||||
|
|
||||||
/// @brief Returns true if a new state has been requested, signaling the current handler to stop.
|
|
||||||
bool NewStatePending() const { return fStateMachine.NewStatePending(); }
|
|
||||||
|
|
||||||
/// @brief Returns the current state
|
|
||||||
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
|
||||||
/// @brief Returns the name of the current state as a string
|
|
||||||
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
|
||||||
|
|
||||||
/// @brief Returns name of the given state as a string
|
|
||||||
/// @param state state
|
|
||||||
static std::string GetStateName(const fair::mq::State state) { return fair::mq::GetStateName(state); }
|
|
||||||
/// @brief Returns name of the given transition as a string
|
|
||||||
/// @param transition transition
|
|
||||||
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::GetTransitionName(transition); }
|
|
||||||
|
|
||||||
static constexpr const char* DefaultId = "";
|
|
||||||
static constexpr int DefaultIOThreads = 1;
|
|
||||||
static constexpr const char* DefaultTransportName = "zeromq";
|
|
||||||
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::ZMQ;
|
|
||||||
static constexpr const char* DefaultNetworkInterface = "default";
|
|
||||||
static constexpr int DefaultInitTimeout = 120;
|
|
||||||
static constexpr uint64_t DefaultMaxRunTime = 0;
|
|
||||||
static constexpr float DefaultRate = 0.;
|
|
||||||
static constexpr const char* DefaultSession = "default";
|
|
||||||
|
|
||||||
private:
|
|
||||||
fair::mq::Transport fDefaultTransportType; ///< Default transport for the device
|
|
||||||
fair::mq::StateMachine fStateMachine;
|
|
||||||
|
|
||||||
/// Handles the initialization
|
|
||||||
void InitWrapper();
|
|
||||||
/// Initializes binding channels
|
|
||||||
void BindWrapper();
|
|
||||||
/// Initializes connecting channels
|
|
||||||
void ConnectWrapper();
|
|
||||||
/// Handles the InitTask() method
|
|
||||||
void InitTaskWrapper();
|
|
||||||
/// Handles the Run() method
|
|
||||||
void RunWrapper();
|
|
||||||
/// Handles the ResetTask() method
|
|
||||||
void ResetTaskWrapper();
|
|
||||||
/// Handles the Reset() method
|
|
||||||
void ResetWrapper();
|
|
||||||
|
|
||||||
/// Notifies transports to cease any blocking activity
|
|
||||||
void UnblockTransports();
|
|
||||||
|
|
||||||
/// Shuts down the transports and the device
|
|
||||||
void Exit() {}
|
|
||||||
|
|
||||||
/// Attach (bind/connect) channels in the list
|
|
||||||
void AttachChannels(std::vector<FairMQChannel*>& chans);
|
|
||||||
bool AttachChannel(FairMQChannel& ch);
|
|
||||||
|
|
||||||
void HandleSingleChannelInput();
|
|
||||||
void HandleMultipleChannelInput();
|
|
||||||
void HandleMultipleTransportInput();
|
|
||||||
void PollForTransport(const FairMQTransportFactory* factory, const std::vector<std::string>& channelKeys);
|
|
||||||
|
|
||||||
bool HandleMsgInput(const std::string& chName, const InputMsgCallback& callback, int i);
|
|
||||||
bool HandleMultipartInput(const std::string& chName, const InputMultipartCallback& callback, int i);
|
|
||||||
|
|
||||||
std::vector<FairMQChannel*> fUninitializedBindingChannels;
|
|
||||||
std::vector<FairMQChannel*> fUninitializedConnectingChannels;
|
|
||||||
|
|
||||||
bool fDataCallbacks;
|
|
||||||
std::unordered_map<std::string, InputMsgCallback> fMsgInputs;
|
|
||||||
std::unordered_map<std::string, InputMultipartCallback> fMultipartInputs;
|
|
||||||
std::unordered_map<fair::mq::Transport, std::vector<std::string>> fMultitransportInputs;
|
|
||||||
std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> fChannelRegistry;
|
|
||||||
std::vector<std::string> fInputChannelKeys;
|
|
||||||
std::mutex fMultitransportMutex;
|
|
||||||
std::atomic<bool> fMultitransportProceed;
|
|
||||||
|
|
||||||
const fair::mq::tools::Version fVersion;
|
|
||||||
float fRate; ///< Rate limiting for ConditionalRun
|
|
||||||
uint64_t fMaxRunRuntimeInS; ///< Maximum runtime for the Running state handler, after which state will change to Ready (in seconds, 0 for no limit).
|
|
||||||
int fInitializationTimeoutInS;
|
|
||||||
std::vector<std::string> fRawCmdLineArgs;
|
|
||||||
|
|
||||||
fair::mq::StateQueue fStateQueue;
|
|
||||||
|
|
||||||
std::mutex fTransitionMtx;
|
|
||||||
bool fTransitioning;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FAIRMQDEVICE_H_ */
|
#endif /* FAIRMQDEVICE_H_ */
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
/**
|
|
||||||
* FairMQLogger.cxx
|
|
||||||
*
|
|
||||||
* @since 2012-12-04
|
|
||||||
* @author D. Klein, A. Rybalchenko
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "FairMQLogger.h"
|
|
|
@ -1,13 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
/**
|
|
||||||
* FairMQMessage.cxx
|
|
||||||
*
|
|
||||||
* @since 2012-12-05
|
|
||||||
* @author D. Klein, A. Rybalchenko
|
|
||||||
*/
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,65 +9,12 @@
|
||||||
#ifndef FAIRMQMESSAGE_H_
|
#ifndef FAIRMQMESSAGE_H_
|
||||||
#define FAIRMQMESSAGE_H_
|
#define FAIRMQMESSAGE_H_
|
||||||
|
|
||||||
#include <cstddef> // for size_t
|
#if 0
|
||||||
#include <memory> // unique_ptr
|
#ifndef FAIR_MQ_MESSAGE_H
|
||||||
#include <stdexcept>
|
#pragma GCC warning "Deprecated header: Use <fairmq/Message.h> instead"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <fairmq/Transports.h>
|
#include <fairmq/Message.h>
|
||||||
|
|
||||||
using fairmq_free_fn = void(void* data, void* hint);
|
|
||||||
class FairMQTransportFactory;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
struct Alignment
|
|
||||||
{
|
|
||||||
size_t alignment;
|
|
||||||
explicit operator size_t() const { return alignment; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
class FairMQMessage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FairMQMessage() = default;
|
|
||||||
FairMQMessage(FairMQTransportFactory* factory) : fTransport(factory) {}
|
|
||||||
|
|
||||||
virtual void Rebuild() = 0;
|
|
||||||
virtual void Rebuild(fair::mq::Alignment alignment) = 0;
|
|
||||||
virtual void Rebuild(const size_t size) = 0;
|
|
||||||
virtual void Rebuild(const size_t size, fair::mq::Alignment alignment) = 0;
|
|
||||||
virtual void Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
|
||||||
|
|
||||||
virtual void* GetData() const = 0;
|
|
||||||
virtual size_t GetSize() const = 0;
|
|
||||||
|
|
||||||
virtual bool SetUsedSize(const size_t size) = 0;
|
|
||||||
|
|
||||||
virtual fair::mq::Transport GetType() const = 0;
|
|
||||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
|
||||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
|
||||||
|
|
||||||
virtual void Copy(const FairMQMessage& msg) = 0;
|
|
||||||
|
|
||||||
virtual ~FairMQMessage() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
FairMQTransportFactory* fTransport{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
using FairMQMessagePtr = std::unique_ptr<FairMQMessage>;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
using Message = FairMQMessage;
|
|
||||||
using MessagePtr = FairMQMessagePtr;
|
|
||||||
struct MessageError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
struct MessageBadAlloc : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
#endif /* FAIRMQMESSAGE_H_ */
|
#endif /* FAIRMQMESSAGE_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,90 +9,12 @@
|
||||||
#ifndef FAIRMQPARTS_H_
|
#ifndef FAIRMQPARTS_H_
|
||||||
#define FAIRMQPARTS_H_
|
#define FAIRMQPARTS_H_
|
||||||
|
|
||||||
#include "FairMQTransportFactory.h"
|
#if 0
|
||||||
#include "FairMQMessage.h"
|
#ifndef FAIR_MQ_PARTS_H
|
||||||
|
#pragma GCC warning "Deprecated header: Use <fairmq/Parts.h> instead"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <fairmq/Parts.h>
|
||||||
#include <memory> // unique_ptr
|
|
||||||
|
|
||||||
/// FairMQParts is a lightweight convenience wrapper around a vector of unique pointers to FairMQMessage, used for sending multi-part messages
|
|
||||||
|
|
||||||
class FairMQParts
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
using container = std::vector<std::unique_ptr<FairMQMessage>>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Default constructor
|
|
||||||
FairMQParts() = default;
|
|
||||||
/// Copy Constructor
|
|
||||||
FairMQParts(const FairMQParts&) = delete;
|
|
||||||
/// Move constructor
|
|
||||||
FairMQParts(FairMQParts&& p) = default;
|
|
||||||
/// Assignment operator
|
|
||||||
FairMQParts& operator=(const FairMQParts&) = delete;
|
|
||||||
/// Constructor from argument pack of std::unique_ptr<FairMQMessage> rvalues
|
|
||||||
template <typename... Ts>
|
|
||||||
FairMQParts(Ts&&... messages) { AddPart(std::forward<Ts>(messages)...); }
|
|
||||||
/// Default destructor
|
|
||||||
~FairMQParts() = default;
|
|
||||||
|
|
||||||
/// Adds part (FairMQMessage) to the container
|
|
||||||
/// @param msg message pointer (for example created with NewMessage() method of FairMQDevice)
|
|
||||||
void AddPart(FairMQMessage* msg)
|
|
||||||
{
|
|
||||||
fParts.push_back(std::unique_ptr<FairMQMessage>(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds part (std::unique_ptr<FairMQMessage>&) to the container (move)
|
|
||||||
/// @param msg unique pointer to FairMQMessage
|
|
||||||
/// rvalue ref (move required when passing argument)
|
|
||||||
void AddPart(std::unique_ptr<FairMQMessage>&& msg)
|
|
||||||
{
|
|
||||||
fParts.push_back(std::move(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add variable list of parts to the container (move)
|
|
||||||
template <typename... Ts>
|
|
||||||
void AddPart(std::unique_ptr<FairMQMessage>&& first, Ts&&... remaining)
|
|
||||||
{
|
|
||||||
AddPart(std::move(first));
|
|
||||||
AddPart(std::forward<Ts>(remaining)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add content of another object by move
|
|
||||||
void AddPart(FairMQParts&& other)
|
|
||||||
{
|
|
||||||
container parts = std::move(other.fParts);
|
|
||||||
for (auto& part : parts) {
|
|
||||||
fParts.push_back(std::move(part));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get reference to part in the container at index (without bounds check)
|
|
||||||
/// @param index container index
|
|
||||||
FairMQMessage& operator[](const int index) { return *(fParts[index]); }
|
|
||||||
|
|
||||||
/// Get reference to unique pointer to part in the container at index (with bounds check)
|
|
||||||
/// @param index container index
|
|
||||||
std::unique_ptr<FairMQMessage>& At(const int index) { return fParts.at(index); }
|
|
||||||
|
|
||||||
// ref version
|
|
||||||
FairMQMessage& AtRef(const int index) { return *(fParts.at(index)); }
|
|
||||||
|
|
||||||
/// Get number of parts in the container
|
|
||||||
/// @return number of parts in the container
|
|
||||||
int Size() const { return fParts.size(); }
|
|
||||||
|
|
||||||
container fParts;
|
|
||||||
|
|
||||||
// forward container iterators
|
|
||||||
using iterator = container::iterator;
|
|
||||||
using const_iterator = container::const_iterator;
|
|
||||||
auto begin() -> decltype(fParts.begin()) { return fParts.begin(); }
|
|
||||||
auto end() -> decltype(fParts.end()) { return fParts.end(); }
|
|
||||||
auto cbegin() -> decltype(fParts.cbegin()) { return fParts.cbegin(); }
|
|
||||||
auto cend() -> decltype(fParts.cend()) { return fParts.cend(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FAIRMQPARTS_H_ */
|
#endif /* FAIRMQPARTS_H_ */
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
/**
|
|
||||||
* FairMQPoller.cxx
|
|
||||||
*
|
|
||||||
* @since 2014-01-23
|
|
||||||
* @author A. Rybalchenko
|
|
||||||
*/
|
|
|
@ -9,31 +9,12 @@
|
||||||
#ifndef FAIRMQPOLLER_H_
|
#ifndef FAIRMQPOLLER_H_
|
||||||
#define FAIRMQPOLLER_H_
|
#define FAIRMQPOLLER_H_
|
||||||
|
|
||||||
#include <memory>
|
#if 0
|
||||||
#include <stdexcept>
|
#ifndef FAIR_MQ_POLLER_H
|
||||||
#include <string>
|
#pragma GCC warning "Deprecated header: Use <fairmq/Poller.h> instead"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
class FairMQPoller
|
#include <fairmq/Poller.h>
|
||||||
{
|
|
||||||
public:
|
|
||||||
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() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
using FairMQPollerPtr = std::unique_ptr<FairMQPoller>;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
using Poller = FairMQPoller;
|
|
||||||
using PollerPtr = FairMQPollerPtr;
|
|
||||||
struct PollerError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
#endif /* FAIRMQPOLLER_H_ */
|
#endif /* FAIRMQPOLLER_H_ */
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include <FairMQSocket.h>
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,88 +9,12 @@
|
||||||
#ifndef FAIRMQSOCKET_H_
|
#ifndef FAIRMQSOCKET_H_
|
||||||
#define FAIRMQSOCKET_H_
|
#define FAIRMQSOCKET_H_
|
||||||
|
|
||||||
#include "FairMQMessage.h"
|
#if 0
|
||||||
|
#ifndef FAIR_MQ_SOCKET_H
|
||||||
|
#pragma GCC warning "Deprecated header: Use <fairmq/Socket.h> instead"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <fairmq/Socket.h>
|
||||||
#include <ostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class FairMQTransportFactory;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
enum class TransferCode : int
|
|
||||||
{
|
|
||||||
success = 0,
|
|
||||||
error = -1,
|
|
||||||
timeout = -2,
|
|
||||||
interrupted = -3
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
class FairMQSocket
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FairMQSocket() = default;
|
|
||||||
FairMQSocket(FairMQTransportFactory* fac) : fTransport(fac) {}
|
|
||||||
|
|
||||||
virtual std::string GetId() const = 0;
|
|
||||||
|
|
||||||
virtual bool Bind(const std::string& address) = 0;
|
|
||||||
virtual bool Connect(const std::string& address) = 0;
|
|
||||||
|
|
||||||
virtual int64_t Send(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
|
||||||
virtual int64_t Receive(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
|
||||||
virtual int64_t Send(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
|
|
||||||
virtual int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
|
|
||||||
|
|
||||||
virtual void Close() = 0;
|
|
||||||
|
|
||||||
virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0;
|
|
||||||
virtual void GetOption(const std::string& option, void* value, size_t* valueSize) = 0;
|
|
||||||
|
|
||||||
/// If the backend supports it, fills the unsigned integer @a events with the ZMQ_EVENTS value
|
|
||||||
/// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in
|
|
||||||
/// the future.
|
|
||||||
virtual int Events(uint32_t* events) = 0;
|
|
||||||
virtual void SetLinger(const int value) = 0;
|
|
||||||
virtual int GetLinger() const = 0;
|
|
||||||
virtual void SetSndBufSize(const int value) = 0;
|
|
||||||
virtual int GetSndBufSize() const = 0;
|
|
||||||
virtual void SetRcvBufSize(const int value) = 0;
|
|
||||||
virtual int GetRcvBufSize() const = 0;
|
|
||||||
virtual void SetSndKernelSize(const int value) = 0;
|
|
||||||
virtual int GetSndKernelSize() const = 0;
|
|
||||||
virtual void SetRcvKernelSize(const int value) = 0;
|
|
||||||
virtual int GetRcvKernelSize() const = 0;
|
|
||||||
|
|
||||||
virtual unsigned long GetBytesTx() const = 0;
|
|
||||||
virtual unsigned long GetBytesRx() const = 0;
|
|
||||||
virtual unsigned long GetMessagesTx() const = 0;
|
|
||||||
virtual unsigned long GetMessagesRx() const = 0;
|
|
||||||
|
|
||||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
|
||||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
|
||||||
|
|
||||||
virtual ~FairMQSocket() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
FairMQTransportFactory* fTransport{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
using FairMQSocketPtr = std::unique_ptr<FairMQSocket>;
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
using Socket = FairMQSocket;
|
|
||||||
using SocketPtr = FairMQSocketPtr;
|
|
||||||
struct SocketError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
#endif /* FAIRMQSOCKET_H_ */
|
#endif /* FAIRMQSOCKET_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,174 +9,12 @@
|
||||||
#ifndef FAIRMQTRANSPORTFACTORY_H_
|
#ifndef FAIRMQTRANSPORTFACTORY_H_
|
||||||
#define FAIRMQTRANSPORTFACTORY_H_
|
#define FAIRMQTRANSPORTFACTORY_H_
|
||||||
|
|
||||||
#include <FairMQMessage.h>
|
#if 0
|
||||||
#include <FairMQPoller.h>
|
#ifndef FAIR_MQ_TRANSPORTFACTORY_H
|
||||||
#include <FairMQSocket.h>
|
#pragma GCC warning "Deprecated header: Use <fairmq/TransportFactory.h> instead"
|
||||||
#include <FairMQUnmanagedRegion.h>
|
#endif
|
||||||
#include <fairmq/MemoryResources.h>
|
#endif
|
||||||
#include <fairmq/Transports.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <fairmq/TransportFactory.h>
|
||||||
#include <memory> // shared_ptr
|
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <cstddef> // size_t
|
|
||||||
|
|
||||||
class FairMQChannel;
|
|
||||||
namespace fair::mq { class ProgOptions; }
|
|
||||||
|
|
||||||
class FairMQTransportFactory
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/// Topology wide unique id
|
|
||||||
const std::string fkId;
|
|
||||||
|
|
||||||
/// The polymorphic memory resource associated with the transport
|
|
||||||
fair::mq::ChannelResource fMemoryResource{this};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// ctor
|
|
||||||
/// @param id Topology wide unique id, usually the device id.
|
|
||||||
FairMQTransportFactory(std::string id);
|
|
||||||
|
|
||||||
auto GetId() const -> const std::string { return fkId; };
|
|
||||||
|
|
||||||
/// Get a pointer to the associated polymorphic memory resource
|
|
||||||
fair::mq::ChannelResource* GetMemoryResource() { return &fMemoryResource; }
|
|
||||||
operator fair::mq::ChannelResource*() { return &fMemoryResource; }
|
|
||||||
|
|
||||||
/// @brief Create empty FairMQMessage (for receiving)
|
|
||||||
/// @return pointer to FairMQMessage
|
|
||||||
virtual FairMQMessagePtr CreateMessage() = 0;
|
|
||||||
/// @brief Create empty FairMQMessage (for receiving), align received buffer to specified alignment
|
|
||||||
/// @param alignment alignment to align received buffer to
|
|
||||||
/// @return pointer to FairMQMessage
|
|
||||||
virtual FairMQMessagePtr CreateMessage(fair::mq::Alignment alignment) = 0;
|
|
||||||
/// @brief Create new FairMQMessage of specified size
|
|
||||||
/// @param size message size
|
|
||||||
/// @return pointer to FairMQMessage
|
|
||||||
virtual FairMQMessagePtr CreateMessage(const size_t size) = 0;
|
|
||||||
/// @brief Create new FairMQMessage of specified size and alignment
|
|
||||||
/// @param size message size
|
|
||||||
/// @param alignment message alignment
|
|
||||||
/// @return pointer to FairMQMessage
|
|
||||||
virtual FairMQMessagePtr CreateMessage(const size_t size, fair::mq::Alignment alignment) = 0;
|
|
||||||
/// @brief Create new FairMQMessage with user provided buffer and size
|
|
||||||
/// @param data pointer to user provided buffer
|
|
||||||
/// @param size size of the user provided buffer
|
|
||||||
/// @param ffn callback, called when the message is transfered (and can be deleted)
|
|
||||||
/// @param obj optional helper pointer that can be used in the callback
|
|
||||||
/// @return pointer to FairMQMessage
|
|
||||||
virtual FairMQMessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
|
||||||
/// @brief create a message with the buffer located within the corresponding unmanaged region
|
|
||||||
/// @param unmanagedRegion the unmanaged region that this message buffer belongs to
|
|
||||||
/// @param data message buffer (must be within the region - checked at runtime by the transport)
|
|
||||||
/// @param size size of the message
|
|
||||||
/// @param hint optional parameter, returned to the user in the FairMQRegionCallback
|
|
||||||
virtual FairMQMessagePtr CreateMessage(FairMQUnmanagedRegionPtr& unmanagedRegion, void* data, const size_t size, void* hint = 0) = 0;
|
|
||||||
|
|
||||||
/// @brief Create a socket
|
|
||||||
virtual FairMQSocketPtr CreateSocket(const std::string& type, const std::string& name) = 0;
|
|
||||||
|
|
||||||
/// @brief Create a poller for a single channel (all subchannels)
|
|
||||||
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel>& channels) const = 0;
|
|
||||||
/// @brief Create a poller for specific channels
|
|
||||||
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel*>& channels) const = 0;
|
|
||||||
/// @brief Create a poller for specific channels (all subchannels)
|
|
||||||
virtual FairMQPollerPtr CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const = 0;
|
|
||||||
|
|
||||||
/// @brief Create new UnmanagedRegion
|
|
||||||
/// @param size size of the region
|
|
||||||
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
|
|
||||||
/// @param path optional parameter to pass to the underlying transport
|
|
||||||
/// @param flags optional parameter to pass to the underlying transport
|
|
||||||
/// @return pointer to UnmanagedRegion
|
|
||||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
|
|
||||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
|
|
||||||
/// @brief Create new UnmanagedRegion
|
|
||||||
/// @param size size of the region
|
|
||||||
/// @param userFlags flags to be stored with the region, have no effect on the transport, but can be retrieved from the region by the user
|
|
||||||
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
|
|
||||||
/// @param path optional parameter to pass to the underlying transport
|
|
||||||
/// @param flags optional parameter to pass to the underlying transport
|
|
||||||
/// @return pointer to UnmanagedRegion
|
|
||||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
|
|
||||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
|
|
||||||
|
|
||||||
/// @brief Subscribe to region events (creation, destruction, ...)
|
|
||||||
/// @param callback the callback that is called when a region event occurs
|
|
||||||
virtual void SubscribeToRegionEvents(FairMQRegionEventCallback callback) = 0;
|
|
||||||
/// @brief Check if there is an active subscription to region events
|
|
||||||
/// @return true/false
|
|
||||||
virtual bool SubscribedToRegionEvents() = 0;
|
|
||||||
/// @brief Unsubscribe from region events
|
|
||||||
virtual void UnsubscribeFromRegionEvents() = 0;
|
|
||||||
|
|
||||||
virtual std::vector<FairMQRegionInfo> GetRegionInfo() = 0;
|
|
||||||
|
|
||||||
/// Get transport type
|
|
||||||
virtual fair::mq::Transport GetType() const = 0;
|
|
||||||
|
|
||||||
virtual void Interrupt() = 0;
|
|
||||||
virtual void Resume() = 0;
|
|
||||||
virtual void Reset() = 0;
|
|
||||||
|
|
||||||
virtual ~FairMQTransportFactory() = default;
|
|
||||||
|
|
||||||
static auto CreateTransportFactory(const std::string& type, const std::string& id = "", const fair::mq::ProgOptions* config = nullptr) -> std::shared_ptr<FairMQTransportFactory>;
|
|
||||||
|
|
||||||
static void FairMQNoCleanup(void* /*data*/, void* /*obj*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static void FairMQSimpleMsgCleanup(void* /*data*/, void* obj)
|
|
||||||
{
|
|
||||||
delete static_cast<T*>(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewSimpleMessage(const T& data)
|
|
||||||
{
|
|
||||||
// todo: is_trivially_copyable not available on gcc < 5, workaround?
|
|
||||||
// static_assert(std::is_trivially_copyable<T>::value, "The argument type for NewSimpleMessage has to be trivially copyable!");
|
|
||||||
T* dataCopy = new T(data);
|
|
||||||
return CreateMessage(dataCopy, sizeof(T), FairMQSimpleMsgCleanup<T>, dataCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
FairMQMessagePtr NewSimpleMessage(const char(&data)[N])
|
|
||||||
{
|
|
||||||
std::string* msgStr = new std::string(data);
|
|
||||||
return CreateMessage(const_cast<char*>(msgStr->c_str()), msgStr->length(), FairMQSimpleMsgCleanup<std::string>, msgStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQMessagePtr NewSimpleMessage(const std::string& str)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string* msgStr = new std::string(str);
|
|
||||||
return CreateMessage(const_cast<char*>(msgStr->c_str()), msgStr->length(), FairMQSimpleMsgCleanup<std::string>, msgStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
FairMQMessagePtr NewStaticMessage(const T& data)
|
|
||||||
{
|
|
||||||
return CreateMessage(data, sizeof(T), FairMQNoCleanup, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQMessagePtr NewStaticMessage(const std::string& str)
|
|
||||||
{
|
|
||||||
return CreateMessage(const_cast<char*>(str.c_str()), str.length(), FairMQNoCleanup, nullptr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
using TransportFactory = FairMQTransportFactory;
|
|
||||||
struct TransportFactoryError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
#endif /* FAIRMQTRANSPORTFACTORY_H_ */
|
#endif /* FAIRMQTRANSPORTFACTORY_H_ */
|
||||||
|
|
|
@ -9,120 +9,12 @@
|
||||||
#ifndef FAIRMQUNMANAGEDREGION_H_
|
#ifndef FAIRMQUNMANAGEDREGION_H_
|
||||||
#define FAIRMQUNMANAGEDREGION_H_
|
#define FAIRMQUNMANAGEDREGION_H_
|
||||||
|
|
||||||
#include <cstddef> // size_t
|
#if 0
|
||||||
#include <cstdint> // uint32_t
|
#ifndef FAIR_MQ_UNMANAGEDREGION_H
|
||||||
#include <fairmq/Transports.h>
|
#pragma GCC warning "Deprecated header: Use <fairmq/UnmanagedRegion.h> instead"
|
||||||
#include <functional> // std::function
|
#endif
|
||||||
#include <memory> // std::unique_ptr
|
#endif
|
||||||
#include <ostream> // std::ostream
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class FairMQTransportFactory;
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
|
||||||
enum class FairMQRegionEvent : int
|
|
||||||
{
|
|
||||||
created,
|
|
||||||
destroyed,
|
|
||||||
local_only
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FairMQRegionInfo
|
|
||||||
{
|
|
||||||
FairMQRegionInfo() = default;
|
|
||||||
|
|
||||||
FairMQRegionInfo(bool _managed, uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
|
|
||||||
: managed(_managed)
|
|
||||||
, id(_id)
|
|
||||||
, ptr(_ptr)
|
|
||||||
, size(_size)
|
|
||||||
, flags(_flags)
|
|
||||||
, event(_event)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool managed = true; // managed/unmanaged
|
|
||||||
uint64_t id = 0; // id of the region
|
|
||||||
void* ptr = nullptr; // pointer to the start of the region
|
|
||||||
size_t size = 0; // region size
|
|
||||||
int64_t flags = 0; // custom flags set by the creator
|
|
||||||
FairMQRegionEvent event = FairMQRegionEvent::created;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FairMQRegionBlock {
|
|
||||||
void* ptr;
|
|
||||||
size_t size;
|
|
||||||
void* hint;
|
|
||||||
|
|
||||||
FairMQRegionBlock(void* p, size_t s, void* h)
|
|
||||||
: ptr(p), size(s), hint(h)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
using FairMQRegionCallback = std::function<void(void*, size_t, void*)>;
|
|
||||||
using FairMQRegionBulkCallback = std::function<void(const std::vector<FairMQRegionBlock>&)>;
|
|
||||||
using FairMQRegionEventCallback = std::function<void(FairMQRegionInfo)>;
|
|
||||||
|
|
||||||
class FairMQUnmanagedRegion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FairMQUnmanagedRegion() = default;
|
|
||||||
FairMQUnmanagedRegion(FairMQTransportFactory* factory) : fTransport(factory) {}
|
|
||||||
|
|
||||||
virtual void* GetData() const = 0;
|
|
||||||
virtual size_t GetSize() const = 0;
|
|
||||||
virtual uint16_t GetId() const = 0;
|
|
||||||
virtual void SetLinger(uint32_t linger) = 0;
|
|
||||||
virtual uint32_t GetLinger() const = 0;
|
|
||||||
|
|
||||||
virtual fair::mq::Transport GetType() const = 0;
|
|
||||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
|
||||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
|
||||||
|
|
||||||
virtual ~FairMQUnmanagedRegion() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
FairMQTransportFactory* fTransport{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
using FairMQUnmanagedRegionPtr = std::unique_ptr<FairMQUnmanagedRegion>;
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const FairMQRegionEvent& event)
|
|
||||||
{
|
|
||||||
switch (event) {
|
|
||||||
case FairMQRegionEvent::created:
|
|
||||||
return os << "created";
|
|
||||||
case FairMQRegionEvent::destroyed:
|
|
||||||
return os << "destroyed";
|
|
||||||
case FairMQRegionEvent::local_only:
|
|
||||||
return os << "local_only";
|
|
||||||
default:
|
|
||||||
return os << "unrecognized event";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace fair::mq
|
|
||||||
{
|
|
||||||
|
|
||||||
struct RegionConfig
|
|
||||||
{
|
|
||||||
RegionConfig() = default;
|
|
||||||
|
|
||||||
RegionConfig(bool l, bool z)
|
|
||||||
: lock(l), zero(z)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool lock = false;
|
|
||||||
bool zero = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
using RegionCallback = FairMQRegionCallback;
|
|
||||||
using RegionBulkCallback = FairMQRegionBulkCallback;
|
|
||||||
using RegionEventCallback = FairMQRegionEventCallback;
|
|
||||||
using RegionEvent = FairMQRegionEvent;
|
|
||||||
using RegionInfo = FairMQRegionInfo;
|
|
||||||
using RegionBlock = FairMQRegionBlock;
|
|
||||||
using UnmanagedRegion = FairMQUnmanagedRegion;
|
|
||||||
using UnmanagedRegionPtr = FairMQUnmanagedRegionPtr;
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
||||||
|
|
||||||
#endif /* FAIRMQUNMANAGEDREGION_H_ */
|
#endif /* FAIRMQUNMANAGEDREGION_H_ */
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
||||||
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
/// @brief Memory allocators and interfaces related to managing memory via the
|
/// @brief Memory allocators and interfaces related to managing memory via the
|
||||||
|
@ -15,27 +15,24 @@
|
||||||
#ifndef FAIR_MQ_MEMORY_RESOURCES_H
|
#ifndef FAIR_MQ_MEMORY_RESOURCES_H
|
||||||
#define FAIR_MQ_MEMORY_RESOURCES_H
|
#define FAIR_MQ_MEMORY_RESOURCES_H
|
||||||
|
|
||||||
#include <FairMQMessage.h>
|
|
||||||
class FairMQTransportFactory;
|
|
||||||
|
|
||||||
#include <boost/container/container_fwd.hpp>
|
#include <boost/container/container_fwd.hpp>
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
#include <boost/container/pmr/memory_resource.hpp>
|
#include <boost/container/pmr/memory_resource.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <fairmq/Message.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace fair::mq
|
namespace fair::mq {
|
||||||
{
|
|
||||||
|
|
||||||
|
class TransportFactory;
|
||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
namespace pmr = boost::container::pmr;
|
namespace pmr = boost::container::pmr;
|
||||||
|
|
||||||
/// All FairMQ related memory resources need to inherit from this interface
|
/// All FairMQ related memory resources need to inherit from this interface
|
||||||
/// class for the
|
/// class for the
|
||||||
/// getMessage() api.
|
/// getMessage() api.
|
||||||
class FairMQMemoryResource : public pmr::memory_resource
|
class MemoryResource : public pmr::memory_resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// return the message containing data associated with the pointer (to start
|
/// return the message containing data associated with the pointer (to start
|
||||||
|
@ -43,9 +40,9 @@ class FairMQMemoryResource : public pmr::memory_resource
|
||||||
/// buffer), e.g. pointer returned by std::vector::data() return nullptr if
|
/// buffer), e.g. pointer returned by std::vector::data() return nullptr if
|
||||||
/// returning
|
/// returning
|
||||||
/// a message does not make sense!
|
/// a message does not make sense!
|
||||||
virtual FairMQMessagePtr getMessage(void *p) = 0;
|
virtual MessagePtr getMessage(void* p) = 0;
|
||||||
virtual void *setMessage(FairMQMessagePtr) = 0;
|
virtual void* setMessage(MessagePtr) = 0;
|
||||||
virtual FairMQTransportFactory *getTransportFactory() noexcept = 0;
|
virtual TransportFactory* getTransportFactory() noexcept = 0;
|
||||||
virtual size_t getNumberOfMessages() const noexcept = 0;
|
virtual size_t getNumberOfMessages() const noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,41 +51,42 @@ class FairMQMemoryResource : public pmr::memory_resource
|
||||||
/// delegated to FairMQ so standard (e.g. STL) containers can construct their
|
/// delegated to FairMQ so standard (e.g. STL) containers can construct their
|
||||||
/// stuff in
|
/// stuff in
|
||||||
/// memory regions appropriate for the data channel configuration.
|
/// memory regions appropriate for the data channel configuration.
|
||||||
class ChannelResource : public FairMQMemoryResource
|
class ChannelResource : public MemoryResource
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
FairMQTransportFactory* factory{nullptr};
|
TransportFactory* factory{nullptr};
|
||||||
// TODO: for now a map to keep track of allocations, something else would
|
// TODO: for now a map to keep track of allocations, something else would
|
||||||
// probably be
|
// probably be
|
||||||
// faster, but for now this does not need to be fast.
|
// faster, but for now this does not need to be fast.
|
||||||
boost::container::flat_map<void*, FairMQMessagePtr> messageMap;
|
boost::container::flat_map<void*, MessagePtr> messageMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChannelResource() = delete;
|
ChannelResource() = delete;
|
||||||
|
|
||||||
ChannelResource(FairMQTransportFactory* _factory)
|
ChannelResource(TransportFactory* _factory)
|
||||||
: factory(_factory)
|
: factory(_factory)
|
||||||
{
|
{
|
||||||
if (!_factory) {
|
if (!_factory) {
|
||||||
throw std::runtime_error("Tried to construct from a nullptr FairMQTransportFactory");
|
throw std::runtime_error(
|
||||||
|
"Tried to construct from a nullptr fair::mq::TransportFactory");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FairMQMessagePtr getMessage(void* p) override
|
MessagePtr getMessage(void* p) override
|
||||||
{
|
{
|
||||||
auto mes = std::move(messageMap[p]);
|
auto mes = std::move(messageMap[p]);
|
||||||
messageMap.erase(p);
|
messageMap.erase(p);
|
||||||
return mes;
|
return mes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* setMessage(FairMQMessagePtr message) override
|
void* setMessage(MessagePtr message) override
|
||||||
{
|
{
|
||||||
void* addr = message->GetData();
|
void* addr = message->GetData();
|
||||||
messageMap[addr] = std::move(message);
|
messageMap[addr] = std::move(message);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQTransportFactory* getTransportFactory() noexcept override { return factory; }
|
TransportFactory* getTransportFactory() noexcept override { return factory; }
|
||||||
|
|
||||||
size_t getNumberOfMessages() const noexcept override { return messageMap.size(); }
|
size_t getNumberOfMessages() const noexcept override { return messageMap.size(); }
|
||||||
|
|
||||||
|
@ -99,12 +97,16 @@ class ChannelResource : public FairMQMemoryResource
|
||||||
messageMap.erase(p);
|
messageMap.erase(p);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool do_is_equal(const pmr::memory_resource &other) const noexcept override
|
bool do_is_equal(const pmr::memory_resource& other) const noexcept override
|
||||||
{
|
{
|
||||||
return this == &other;
|
return this == &other;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQMemoryResource [[deprecated("Use fair::mq::MemoryResource")]] =
|
||||||
|
// fair::mq::MemoryResource;
|
||||||
|
using FairMQMemoryResource = fair::mq::MemoryResource;
|
||||||
|
|
||||||
#endif /* FAIR_MQ_MEMORY_RESOURCES_H */
|
#endif /* FAIR_MQ_MEMORY_RESOURCES_H */
|
||||||
|
|
|
@ -9,6 +9,71 @@
|
||||||
#ifndef FAIR_MQ_MESSAGE_H
|
#ifndef FAIR_MQ_MESSAGE_H
|
||||||
#define FAIR_MQ_MESSAGE_H
|
#define FAIR_MQ_MESSAGE_H
|
||||||
|
|
||||||
#include <FairMQMessage.h>
|
#include <cstddef> // for size_t
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
#include <memory> // unique_ptr
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
using FreeFn = void(void* data, void* hint);
|
||||||
|
class TransportFactory;
|
||||||
|
|
||||||
|
struct Alignment
|
||||||
|
{
|
||||||
|
size_t alignment;
|
||||||
|
explicit operator size_t() const { return alignment; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Message
|
||||||
|
{
|
||||||
|
Message() = default;
|
||||||
|
Message(TransportFactory* factory)
|
||||||
|
: fTransport(factory)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void Rebuild() = 0;
|
||||||
|
virtual void Rebuild(Alignment alignment) = 0;
|
||||||
|
virtual void Rebuild(const size_t size) = 0;
|
||||||
|
virtual void Rebuild(const size_t size, Alignment alignment) = 0;
|
||||||
|
virtual void Rebuild(void* data, const size_t size, FreeFn* ffn, void* hint = nullptr) = 0;
|
||||||
|
|
||||||
|
virtual void* GetData() const = 0;
|
||||||
|
virtual size_t GetSize() const = 0;
|
||||||
|
|
||||||
|
virtual bool SetUsedSize(const size_t size) = 0;
|
||||||
|
|
||||||
|
virtual Transport GetType() const = 0;
|
||||||
|
TransportFactory* GetTransport() { return fTransport; }
|
||||||
|
void SetTransport(TransportFactory* transport) { fTransport = transport; }
|
||||||
|
|
||||||
|
virtual void Copy(const Message& msg) = 0;
|
||||||
|
|
||||||
|
virtual ~Message() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TransportFactory* fTransport{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
using MessagePtr = std::unique_ptr<Message>;
|
||||||
|
|
||||||
|
struct MessageError : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MessageBadAlloc : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using fairmq_free_fn [[deprecated("Use fair::mq::FreeFn")]] = fair::mq::FreeFn;
|
||||||
|
// using FairMQMessage [[deprecated("Use fair::mq::Message")]] = fair::mq::Message;
|
||||||
|
// using FairMQMessagePtr [[deprecated("Use fair::mq::MessagePtr")]] = fair::mq::MessagePtr;
|
||||||
|
using fairmq_free_fn = fair::mq::FreeFn;
|
||||||
|
using FairMQMessage = fair::mq::Message;
|
||||||
|
using FairMQMessagePtr = fair::mq::MessagePtr;
|
||||||
|
|
||||||
#endif // FAIR_MQ_MESSAGE_H
|
#endif // FAIR_MQ_MESSAGE_H
|
||||||
|
|
94
fairmq/Parts.h
Normal file
94
fairmq/Parts.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FAIR_MQ_PARTS_H
|
||||||
|
#define FAIR_MQ_PARTS_H
|
||||||
|
|
||||||
|
#include <fairmq/Message.h>
|
||||||
|
#include <memory> // unique_ptr
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
/// fair::mq::Parts is a lightweight convenience wrapper around a vector of unique pointers to
|
||||||
|
/// Message, used for sending multi-part messages
|
||||||
|
class Parts
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using container = std::vector<MessagePtr>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Parts() = default;
|
||||||
|
Parts(const Parts&) = delete;
|
||||||
|
Parts(Parts&& p) = default;
|
||||||
|
Parts& operator=(const Parts&) = delete;
|
||||||
|
template<typename... Ts>
|
||||||
|
Parts(Ts&&... messages)
|
||||||
|
{
|
||||||
|
AddPart(std::forward<Ts>(messages)...);
|
||||||
|
}
|
||||||
|
~Parts() = default;
|
||||||
|
|
||||||
|
/// Adds part (Message) to the container
|
||||||
|
/// @param msg message pointer (for example created with NewMessage() method of Device)
|
||||||
|
void AddPart(Message* msg) { fParts.push_back(MessagePtr(msg)); }
|
||||||
|
|
||||||
|
/// Adds part to the container (move)
|
||||||
|
/// @param msg unique pointer to Message
|
||||||
|
/// rvalue ref (move required when passing argument)
|
||||||
|
void AddPart(MessagePtr&& msg) { fParts.push_back(std::move(msg)); }
|
||||||
|
|
||||||
|
/// Add variable list of parts to the container (move)
|
||||||
|
template<typename... Ts>
|
||||||
|
void AddPart(MessagePtr&& first, Ts&&... remaining)
|
||||||
|
{
|
||||||
|
AddPart(std::move(first));
|
||||||
|
AddPart(std::forward<Ts>(remaining)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add content of another object by move
|
||||||
|
void AddPart(Parts&& other)
|
||||||
|
{
|
||||||
|
container parts = std::move(other.fParts);
|
||||||
|
for (auto& part : parts) {
|
||||||
|
fParts.push_back(std::move(part));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get reference to part in the container at index (without bounds check)
|
||||||
|
/// @param index container index
|
||||||
|
Message& operator[](const int index) { return *(fParts[index]); }
|
||||||
|
|
||||||
|
/// Get reference to unique pointer to part in the container at index (with bounds check)
|
||||||
|
/// @param index container index
|
||||||
|
MessagePtr& At(const int index) { return fParts.at(index); }
|
||||||
|
|
||||||
|
// ref version
|
||||||
|
Message& AtRef(const int index) { return *(fParts.at(index)); }
|
||||||
|
|
||||||
|
/// Get number of parts in the container
|
||||||
|
/// @return number of parts in the container
|
||||||
|
int Size() const { return fParts.size(); }
|
||||||
|
|
||||||
|
container fParts;
|
||||||
|
|
||||||
|
// forward container iterators
|
||||||
|
using iterator = container::iterator;
|
||||||
|
using const_iterator = container::const_iterator;
|
||||||
|
auto begin() -> decltype(fParts.begin()) { return fParts.begin(); }
|
||||||
|
auto end() -> decltype(fParts.end()) { return fParts.end(); }
|
||||||
|
auto cbegin() -> decltype(fParts.cbegin()) { return fParts.cbegin(); }
|
||||||
|
auto cend() -> decltype(fParts.cend()) { return fParts.cend(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQParts [[deprecated("Use fair::mq::Parts")]] = fair::mq::Parts;
|
||||||
|
using FairMQParts = fair::mq::Parts;
|
||||||
|
|
||||||
|
#endif /* FAIR_MQ_PARTS_H */
|
|
@ -9,6 +9,35 @@
|
||||||
#ifndef FAIR_MQ_POLLER_H
|
#ifndef FAIR_MQ_POLLER_H
|
||||||
#define FAIR_MQ_POLLER_H
|
#define FAIR_MQ_POLLER_H
|
||||||
|
|
||||||
#include <FairMQPoller.h>
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
struct Poller
|
||||||
|
{
|
||||||
|
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 ~Poller() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PollerPtr = std::unique_ptr<Poller>;
|
||||||
|
|
||||||
|
struct PollerError : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQPoller [[deprecated("Use fair::mq::Poller")]] = fair::mq::Poller;
|
||||||
|
// using FairMQPollerPtr [[deprecated("Use fair::mq::PollerPtr")]] = fair::mq::PollerPtr;
|
||||||
|
using FairMQPoller = fair::mq::Poller;
|
||||||
|
using FairMQPollerPtr = fair::mq::PollerPtr;
|
||||||
|
|
||||||
#endif // FAIR_MQ_POLLER_H
|
#endif // FAIR_MQ_POLLER_H
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,11 @@
|
||||||
#ifndef FAIR_MQ_PROGOPTIONSFWD_H
|
#ifndef FAIR_MQ_PROGOPTIONSFWD_H
|
||||||
#define FAIR_MQ_PROGOPTIONSFWD_H
|
#define FAIR_MQ_PROGOPTIONSFWD_H
|
||||||
|
|
||||||
namespace fair::mq
|
namespace fair::mq {
|
||||||
{
|
|
||||||
class ProgOptions;
|
class ProgOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// using FairMQProgOptions [[deprecated("Use fair::mq::ProgOptions")]] = fair::mq::ProgOptions;
|
||||||
using FairMQProgOptions = fair::mq::ProgOptions;
|
using FairMQProgOptions = fair::mq::ProgOptions;
|
||||||
|
|
||||||
#endif /* FAIR_MQ_PROGOPTIONSFWD_H */
|
#endif /* FAIR_MQ_PROGOPTIONSFWD_H */
|
||||||
|
|
|
@ -9,6 +9,87 @@
|
||||||
#ifndef FAIR_MQ_SOCKET_H
|
#ifndef FAIR_MQ_SOCKET_H
|
||||||
#define FAIR_MQ_SOCKET_H
|
#define FAIR_MQ_SOCKET_H
|
||||||
|
|
||||||
#include <FairMQSocket.h>
|
#include <fairmq/Message.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
class TransportFactory;
|
||||||
|
|
||||||
|
enum class TransferCode : int
|
||||||
|
{
|
||||||
|
success = 0,
|
||||||
|
error = -1,
|
||||||
|
timeout = -2,
|
||||||
|
interrupted = -3
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Socket
|
||||||
|
{
|
||||||
|
Socket() = default;
|
||||||
|
Socket(TransportFactory* fac)
|
||||||
|
: fTransport(fac)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual std::string GetId() const = 0;
|
||||||
|
|
||||||
|
virtual bool Bind(const std::string& address) = 0;
|
||||||
|
virtual bool Connect(const std::string& address) = 0;
|
||||||
|
|
||||||
|
virtual int64_t Send(MessagePtr& msg, int timeout = -1) = 0;
|
||||||
|
virtual int64_t Receive(MessagePtr& msg, int timeout = -1) = 0;
|
||||||
|
virtual int64_t Send(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
|
||||||
|
virtual int64_t Receive(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
|
||||||
|
|
||||||
|
virtual void Close() = 0;
|
||||||
|
|
||||||
|
virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0;
|
||||||
|
virtual void GetOption(const std::string& option, void* value, size_t* valueSize) = 0;
|
||||||
|
|
||||||
|
/// If the backend supports it, fills the unsigned integer @a events with the ZMQ_EVENTS value
|
||||||
|
/// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in
|
||||||
|
/// the future.
|
||||||
|
virtual int Events(uint32_t* events) = 0;
|
||||||
|
virtual void SetLinger(const int value) = 0;
|
||||||
|
virtual int GetLinger() const = 0;
|
||||||
|
virtual void SetSndBufSize(const int value) = 0;
|
||||||
|
virtual int GetSndBufSize() const = 0;
|
||||||
|
virtual void SetRcvBufSize(const int value) = 0;
|
||||||
|
virtual int GetRcvBufSize() const = 0;
|
||||||
|
virtual void SetSndKernelSize(const int value) = 0;
|
||||||
|
virtual int GetSndKernelSize() const = 0;
|
||||||
|
virtual void SetRcvKernelSize(const int value) = 0;
|
||||||
|
virtual int GetRcvKernelSize() const = 0;
|
||||||
|
|
||||||
|
virtual unsigned long GetBytesTx() const = 0;
|
||||||
|
virtual unsigned long GetBytesRx() const = 0;
|
||||||
|
virtual unsigned long GetMessagesTx() const = 0;
|
||||||
|
virtual unsigned long GetMessagesRx() const = 0;
|
||||||
|
|
||||||
|
TransportFactory* GetTransport() { return fTransport; }
|
||||||
|
void SetTransport(TransportFactory* transport) { fTransport = transport; }
|
||||||
|
|
||||||
|
virtual ~Socket() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TransportFactory* fTransport{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
using SocketPtr = std::unique_ptr<Socket>;
|
||||||
|
|
||||||
|
struct SocketError : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQSocket [[deprecated("Use fair::mq::Socket")]] = fair::mq::Socket;
|
||||||
|
// using FairMQSocketPtr [[deprecated("Use fair::mq::SocketPtr")]] = fair::mq::SocketPtr;
|
||||||
|
using FairMQSocket = fair::mq::Socket;
|
||||||
|
using FairMQSocketPtr = fair::mq::SocketPtr;
|
||||||
|
|
||||||
#endif // FAIR_MQ_SOCKET_H
|
#endif // FAIR_MQ_SOCKET_H
|
||||||
|
|
|
@ -1,53 +1,47 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <FairMQTransportFactory.h>
|
#include <fairmq/TransportFactory.h>
|
||||||
#include <fairmq/shmem/TransportFactory.h>
|
#include <fairmq/shmem/TransportFactory.h>
|
||||||
#include <fairmq/zeromq/TransportFactory.h>
|
#include <fairmq/zeromq/TransportFactory.h>
|
||||||
#ifdef BUILD_OFI_TRANSPORT
|
#ifdef BUILD_OFI_TRANSPORT
|
||||||
#include <fairmq/ofi/TransportFactory.h>
|
#include <fairmq/ofi/TransportFactory.h>
|
||||||
#endif
|
#endif
|
||||||
#include <FairMQLogger.h>
|
|
||||||
#include <fairmq/tools/Unique.h>
|
|
||||||
#include <fairmq/tools/Strings.h>
|
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
#include <fairmq/Tools.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
FairMQTransportFactory::FairMQTransportFactory(string id)
|
namespace fair::mq {
|
||||||
: fkId(std::move(id))
|
|
||||||
{}
|
|
||||||
|
|
||||||
auto FairMQTransportFactory::CreateTransportFactory(const string& type,
|
auto TransportFactory::CreateTransportFactory(const string& type,
|
||||||
const string& id,
|
const string& id,
|
||||||
const fair::mq::ProgOptions* config)
|
const ProgOptions* config)
|
||||||
-> shared_ptr<FairMQTransportFactory>
|
-> shared_ptr<TransportFactory>
|
||||||
{
|
{
|
||||||
auto finalId = id;
|
auto finalId = id;
|
||||||
|
|
||||||
// Generate uuid if empty
|
// Generate uuid if empty
|
||||||
if (finalId.empty()) {
|
if (finalId.empty()) {
|
||||||
finalId = fair::mq::tools::Uuid();
|
finalId = tools::Uuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "zeromq") {
|
if (type == "zeromq") {
|
||||||
return make_shared<fair::mq::zmq::TransportFactory>(finalId, config);
|
return make_shared<zmq::TransportFactory>(finalId, config);
|
||||||
} else if (type == "shmem") {
|
} else if (type == "shmem") {
|
||||||
return make_shared<fair::mq::shmem::TransportFactory>(finalId, config);
|
return make_shared<shmem::TransportFactory>(finalId, config);
|
||||||
}
|
}
|
||||||
#ifdef BUILD_OFI_TRANSPORT
|
#ifdef BUILD_OFI_TRANSPORT
|
||||||
else if (type == "ofi") {
|
else if (type == "ofi") {
|
||||||
return make_shared<fair::mq::ofi::TransportFactory>(finalId, config);
|
return make_shared<ofi::TransportFactory>(finalId, config);
|
||||||
}
|
}
|
||||||
#endif /* BUILD_OFI_TRANSPORT */
|
#endif /* BUILD_OFI_TRANSPORT */
|
||||||
else {
|
else {
|
||||||
|
@ -60,6 +54,8 @@ auto FairMQTransportFactory::CreateTransportFactory(const string& type,
|
||||||
<< ", and \"ofi\""
|
<< ", and \"ofi\""
|
||||||
#endif /* BUILD_OFI_TRANSPORT */
|
#endif /* BUILD_OFI_TRANSPORT */
|
||||||
<< ". Exiting.";
|
<< ". Exiting.";
|
||||||
throw fair::mq::TransportFactoryError(fair::mq::tools::ToString("Unavailable transport requested: ", type));
|
throw TransportFactoryError(tools::ToString("Unavailable transport requested: ", type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
|
@ -9,6 +9,220 @@
|
||||||
#ifndef FAIR_MQ_TRANSPORTFACTORY_H
|
#ifndef FAIR_MQ_TRANSPORTFACTORY_H
|
||||||
#define FAIR_MQ_TRANSPORTFACTORY_H
|
#define FAIR_MQ_TRANSPORTFACTORY_H
|
||||||
|
|
||||||
#include <FairMQTransportFactory.h>
|
#include <cstddef> // size_t
|
||||||
|
#include <fairmq/MemoryResources.h>
|
||||||
|
#include <fairmq/Message.h>
|
||||||
|
#include <fairmq/Poller.h>
|
||||||
|
#include <fairmq/Socket.h>
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
#include <memory> // shared_ptr
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
class Channel;
|
||||||
|
class ProgOptions;
|
||||||
|
|
||||||
|
class TransportFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// Topology wide unique id
|
||||||
|
const std::string fkId;
|
||||||
|
|
||||||
|
/// The polymorphic memory resource associated with the transport
|
||||||
|
ChannelResource fMemoryResource{this};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// ctor
|
||||||
|
/// @param id Topology wide unique id, usually the device id.
|
||||||
|
TransportFactory(std::string id)
|
||||||
|
: fkId(std::move(id))
|
||||||
|
{}
|
||||||
|
|
||||||
|
auto GetId() const -> const std::string { return fkId; };
|
||||||
|
|
||||||
|
/// Get a pointer to the associated polymorphic memory resource
|
||||||
|
ChannelResource* GetMemoryResource() { return &fMemoryResource; }
|
||||||
|
operator ChannelResource*() { return &fMemoryResource; }
|
||||||
|
|
||||||
|
/// @brief Create empty Message (for receiving)
|
||||||
|
/// @return pointer to Message
|
||||||
|
virtual MessagePtr CreateMessage() = 0;
|
||||||
|
/// @brief Create empty Message (for receiving), align received buffer to specified alignment
|
||||||
|
/// @param alignment alignment to align received buffer to
|
||||||
|
/// @return pointer to Message
|
||||||
|
virtual MessagePtr CreateMessage(Alignment alignment) = 0;
|
||||||
|
/// @brief Create new Message of specified size
|
||||||
|
/// @param size message size
|
||||||
|
/// @return pointer to Message
|
||||||
|
virtual MessagePtr CreateMessage(const size_t size) = 0;
|
||||||
|
/// @brief Create new Message of specified size and alignment
|
||||||
|
/// @param size message size
|
||||||
|
/// @param alignment message alignment
|
||||||
|
/// @return pointer to Message
|
||||||
|
virtual MessagePtr CreateMessage(const size_t size, Alignment alignment) = 0;
|
||||||
|
/// @brief Create new Message with user provided buffer and size
|
||||||
|
/// @param data pointer to user provided buffer
|
||||||
|
/// @param size size of the user provided buffer
|
||||||
|
/// @param ffn callback, called when the message is transfered (and can be deleted)
|
||||||
|
/// @param obj optional helper pointer that can be used in the callback
|
||||||
|
/// @return pointer to Message
|
||||||
|
virtual MessagePtr CreateMessage(void* data,
|
||||||
|
const size_t size,
|
||||||
|
fairmq_free_fn* ffn,
|
||||||
|
void* hint = nullptr) = 0;
|
||||||
|
/// @brief create a message with the buffer located within the corresponding unmanaged region
|
||||||
|
/// @param unmanagedRegion the unmanaged region that this message buffer belongs to
|
||||||
|
/// @param data message buffer (must be within the region - checked at runtime by the transport)
|
||||||
|
/// @param size size of the message
|
||||||
|
/// @param hint optional parameter, returned to the user in the RegionCallback
|
||||||
|
virtual MessagePtr CreateMessage(UnmanagedRegionPtr& unmanagedRegion,
|
||||||
|
void* data,
|
||||||
|
const size_t size,
|
||||||
|
void* hint = 0) = 0;
|
||||||
|
|
||||||
|
/// @brief Create a socket
|
||||||
|
virtual SocketPtr CreateSocket(const std::string& type, const std::string& name) = 0;
|
||||||
|
|
||||||
|
/// @brief Create a poller for a single channel (all subchannels)
|
||||||
|
virtual PollerPtr CreatePoller(const std::vector<Channel>& channels) const = 0;
|
||||||
|
/// @brief Create a poller for specific channels
|
||||||
|
virtual PollerPtr CreatePoller(const std::vector<Channel*>& channels) const = 0;
|
||||||
|
/// @brief Create a poller for specific channels (all subchannels)
|
||||||
|
virtual PollerPtr CreatePoller(
|
||||||
|
const std::unordered_map<std::string, std::vector<Channel>>& channelsMap,
|
||||||
|
const std::vector<std::string>& channelList) const = 0;
|
||||||
|
|
||||||
|
/// @brief Create new UnmanagedRegion
|
||||||
|
/// @param size size of the region
|
||||||
|
/// @param callback callback to be called when a message belonging to this region is no longer
|
||||||
|
/// needed by the transport
|
||||||
|
/// @param path optional parameter to pass to the underlying transport
|
||||||
|
/// @param flags optional parameter to pass to the underlying transport
|
||||||
|
/// @return pointer to UnmanagedRegion
|
||||||
|
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size,
|
||||||
|
RegionCallback callback = nullptr,
|
||||||
|
const std::string& path = "",
|
||||||
|
int flags = 0,
|
||||||
|
RegionConfig cfg = RegionConfig()) = 0;
|
||||||
|
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size,
|
||||||
|
RegionBulkCallback callback = nullptr,
|
||||||
|
const std::string& path = "",
|
||||||
|
int flags = 0,
|
||||||
|
RegionConfig cfg = RegionConfig()) = 0;
|
||||||
|
/// @brief Create new UnmanagedRegion
|
||||||
|
/// @param size size of the region
|
||||||
|
/// @param userFlags flags to be stored with the region, have no effect on the transport, but
|
||||||
|
/// can be retrieved from the region by the user
|
||||||
|
/// @param callback callback to be called when a message belonging to this region is no longer
|
||||||
|
/// needed by the transport
|
||||||
|
/// @param path optional parameter to pass to the underlying transport
|
||||||
|
/// @param flags optional parameter to pass to the underlying transport
|
||||||
|
/// @return pointer to UnmanagedRegion
|
||||||
|
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size,
|
||||||
|
const int64_t userFlags,
|
||||||
|
RegionCallback callback = nullptr,
|
||||||
|
const std::string& path = "",
|
||||||
|
int flags = 0,
|
||||||
|
RegionConfig cfg = RegionConfig()) = 0;
|
||||||
|
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size,
|
||||||
|
const int64_t userFlags,
|
||||||
|
RegionBulkCallback callback = nullptr,
|
||||||
|
const std::string& path = "",
|
||||||
|
int flags = 0,
|
||||||
|
RegionConfig cfg = RegionConfig()) = 0;
|
||||||
|
|
||||||
|
/// @brief Subscribe to region events (creation, destruction, ...)
|
||||||
|
/// @param callback the callback that is called when a region event occurs
|
||||||
|
virtual void SubscribeToRegionEvents(RegionEventCallback callback) = 0;
|
||||||
|
/// @brief Check if there is an active subscription to region events
|
||||||
|
/// @return true/false
|
||||||
|
virtual bool SubscribedToRegionEvents() = 0;
|
||||||
|
/// @brief Unsubscribe from region events
|
||||||
|
virtual void UnsubscribeFromRegionEvents() = 0;
|
||||||
|
|
||||||
|
virtual std::vector<RegionInfo> GetRegionInfo() = 0;
|
||||||
|
|
||||||
|
/// Get transport type
|
||||||
|
virtual Transport GetType() const = 0;
|
||||||
|
|
||||||
|
virtual void Interrupt() = 0;
|
||||||
|
virtual void Resume() = 0;
|
||||||
|
virtual void Reset() = 0;
|
||||||
|
|
||||||
|
virtual ~TransportFactory() = default;
|
||||||
|
|
||||||
|
static auto CreateTransportFactory(const std::string& type,
|
||||||
|
const std::string& id = "",
|
||||||
|
const ProgOptions* config = nullptr)
|
||||||
|
-> std::shared_ptr<TransportFactory>;
|
||||||
|
|
||||||
|
static void NoCleanup(void* /*data*/, void* /*obj*/) {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void SimpleMsgCleanup(void* /*data*/, void* obj)
|
||||||
|
{
|
||||||
|
delete static_cast<T*>(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewSimpleMessage(const T& data)
|
||||||
|
{
|
||||||
|
// todo: is_trivially_copyable not available on gcc < 5, workaround?
|
||||||
|
// static_assert(std::is_trivially_copyable<T>::value, "The argument type for
|
||||||
|
// NewSimpleMessage has to be trivially copyable!");
|
||||||
|
T* dataCopy = new T(data);
|
||||||
|
return CreateMessage(dataCopy, sizeof(T), SimpleMsgCleanup<T>, dataCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
MessagePtr NewSimpleMessage(const char (&data)[N])
|
||||||
|
{
|
||||||
|
std::string* msgStr = new std::string(data);
|
||||||
|
return CreateMessage(const_cast<char*>(msgStr->c_str()),
|
||||||
|
msgStr->length(),
|
||||||
|
SimpleMsgCleanup<std::string>,
|
||||||
|
msgStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessagePtr NewSimpleMessage(const std::string& str)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string* msgStr = new std::string(str);
|
||||||
|
return CreateMessage(const_cast<char*>(msgStr->c_str()),
|
||||||
|
msgStr->length(),
|
||||||
|
SimpleMsgCleanup<std::string>,
|
||||||
|
msgStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MessagePtr NewStaticMessage(const T& data)
|
||||||
|
{
|
||||||
|
return CreateMessage(data, sizeof(T), NoCleanup, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessagePtr NewStaticMessage(const std::string& str)
|
||||||
|
{
|
||||||
|
return CreateMessage(const_cast<char*>(str.c_str()), str.length(), NoCleanup, nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransportFactoryError : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQTransportFactory [[deprecated("Use fair::mq::TransportFactory")]] =
|
||||||
|
// fair::mq::TransportFactory;
|
||||||
|
// using FairMQTransportFactoryError [[deprecated("Use fair::mq::TransportFactoryError")]] =
|
||||||
|
// fair::mq::TransportFactoryError;
|
||||||
|
using FairMQTransportFactory = fair::mq::TransportFactory;
|
||||||
|
using FairMQTransportFactoryError = fair::mq::TransportFactoryError;
|
||||||
|
|
||||||
#endif // FAIR_MQ_TRANSPORTFACTORY_H
|
#endif // FAIR_MQ_TRANSPORTFACTORY_H
|
||||||
|
|
|
@ -9,6 +9,139 @@
|
||||||
#ifndef FAIR_MQ_UNMANAGEDREGION_H
|
#ifndef FAIR_MQ_UNMANAGEDREGION_H
|
||||||
#define FAIR_MQ_UNMANAGEDREGION_H
|
#define FAIR_MQ_UNMANAGEDREGION_H
|
||||||
|
|
||||||
#include <FairMQUnmanagedRegion.h>
|
#include <cstddef> // size_t
|
||||||
|
#include <cstdint> // uint32_t
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
#include <functional> // std::function
|
||||||
|
#include <memory> // std::unique_ptr
|
||||||
|
#include <ostream> // std::ostream
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace fair::mq {
|
||||||
|
|
||||||
|
class TransportFactory;
|
||||||
|
|
||||||
|
enum class RegionEvent : int
|
||||||
|
{
|
||||||
|
created,
|
||||||
|
destroyed,
|
||||||
|
local_only
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegionInfo
|
||||||
|
{
|
||||||
|
RegionInfo() = default;
|
||||||
|
|
||||||
|
RegionInfo(bool _managed,
|
||||||
|
uint64_t _id,
|
||||||
|
void* _ptr,
|
||||||
|
size_t _size,
|
||||||
|
int64_t _flags,
|
||||||
|
RegionEvent _event)
|
||||||
|
: managed(_managed)
|
||||||
|
, id(_id)
|
||||||
|
, ptr(_ptr)
|
||||||
|
, size(_size)
|
||||||
|
, flags(_flags)
|
||||||
|
, event(_event)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool managed = true; // managed/unmanaged
|
||||||
|
uint64_t id = 0; // id of the region
|
||||||
|
void* ptr = nullptr; // pointer to the start of the region
|
||||||
|
size_t size = 0; // region size
|
||||||
|
int64_t flags = 0; // custom flags set by the creator
|
||||||
|
RegionEvent event = RegionEvent::created;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegionBlock
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
size_t size;
|
||||||
|
void* hint;
|
||||||
|
|
||||||
|
RegionBlock(void* p, size_t s, void* h)
|
||||||
|
: ptr(p)
|
||||||
|
, size(s)
|
||||||
|
, hint(h)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
using RegionCallback = std::function<void(void*, size_t, void*)>;
|
||||||
|
using RegionBulkCallback = std::function<void(const std::vector<RegionBlock>&)>;
|
||||||
|
using RegionEventCallback = std::function<void(RegionInfo)>;
|
||||||
|
|
||||||
|
struct UnmanagedRegion
|
||||||
|
{
|
||||||
|
UnmanagedRegion() = default;
|
||||||
|
UnmanagedRegion(TransportFactory* factory)
|
||||||
|
: fTransport(factory)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void* GetData() const = 0;
|
||||||
|
virtual size_t GetSize() const = 0;
|
||||||
|
virtual uint16_t GetId() const = 0;
|
||||||
|
virtual void SetLinger(uint32_t linger) = 0;
|
||||||
|
virtual uint32_t GetLinger() const = 0;
|
||||||
|
|
||||||
|
virtual Transport GetType() const = 0;
|
||||||
|
TransportFactory* GetTransport() { return fTransport; }
|
||||||
|
void SetTransport(TransportFactory* transport) { fTransport = transport; }
|
||||||
|
|
||||||
|
virtual ~UnmanagedRegion() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TransportFactory* fTransport{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
using UnmanagedRegionPtr = std::unique_ptr<UnmanagedRegion>;
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const RegionEvent& event)
|
||||||
|
{
|
||||||
|
switch (event) {
|
||||||
|
case RegionEvent::created:
|
||||||
|
return os << "created";
|
||||||
|
case RegionEvent::destroyed:
|
||||||
|
return os << "destroyed";
|
||||||
|
case RegionEvent::local_only:
|
||||||
|
return os << "local_only";
|
||||||
|
default:
|
||||||
|
return os << "unrecognized event";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RegionConfig
|
||||||
|
{
|
||||||
|
RegionConfig() = default;
|
||||||
|
|
||||||
|
RegionConfig(bool l, bool z)
|
||||||
|
: lock(l)
|
||||||
|
, zero(z)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool lock = false;
|
||||||
|
bool zero = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
// using FairMQRegionEvent [[deprecated("Use fair::mq::RegionBlock")]] = fair::mq::RegionEvent;
|
||||||
|
// using FairMQRegionInfo [[deprecated("Use fair::mq::RegionInfo")]] = fair::mq::RegionInfo;
|
||||||
|
// using FairMQRegionBlock [[deprecated("Use fair::mq::RegionBlock")]] = fair::mq::RegionBlock;
|
||||||
|
// using FairMQRegionCallback [[deprecated("Use fair::mq::RegionCallback")]] = fair::mq::RegionCallback;
|
||||||
|
// using FairMQRegionBulkCallback [[deprecated("Use fair::mq::RegionBulkCallback")]] = fair::mq::RegionBulkCallback;
|
||||||
|
// using FairMQRegionEventCallback [[deprecated("Use fair::mq::RegionEventCallback")]] = fair::mq::RegionEventCallback;
|
||||||
|
// using FairMQUnmanagedRegion [[deprecated("Use fair::mq::UnmanagedRegion")]] = fair::mq::UnmanagedRegion;
|
||||||
|
// using FairMQUnmanagedRegionPtr [[deprecated("Use fair::mq::UnmanagedRegionPtr")]] = fair::mq::UnmanagedRegionPtr;
|
||||||
|
// using FairMQRegionConfig [[deprecated("Use fair::mq::RegionConfig")]] = fair::mq::RegionConfig;
|
||||||
|
using FairMQRegionEvent = fair::mq::RegionEvent;
|
||||||
|
using FairMQRegionInfo = fair::mq::RegionInfo;
|
||||||
|
using FairMQRegionBlock = fair::mq::RegionBlock;
|
||||||
|
using FairMQRegionCallback = fair::mq::RegionCallback;
|
||||||
|
using FairMQRegionBulkCallback = fair::mq::RegionBulkCallback;
|
||||||
|
using FairMQRegionEventCallback = fair::mq::RegionEventCallback;
|
||||||
|
using FairMQUnmanagedRegion = fair::mq::UnmanagedRegion;
|
||||||
|
using FairMQUnmanagedRegionPtr = fair::mq::UnmanagedRegionPtr;
|
||||||
|
using FairMQRegionConfig = fair::mq::RegionConfig;
|
||||||
|
|
||||||
#endif // FAIR_MQ_UNMANAGEDREGION_H
|
#endif // FAIR_MQ_UNMANAGEDREGION_H
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -19,8 +19,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class FairMQChannel;
|
|
||||||
|
|
||||||
namespace fair::mq::shmem
|
namespace fair::mq::shmem
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -22,7 +22,9 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory> // make_unique
|
#include <memory> // make_unique
|
||||||
|
|
||||||
class FairMQTransportFactory;
|
namespace fair::mq {
|
||||||
|
class TransportFactory;
|
||||||
|
}
|
||||||
|
|
||||||
namespace fair::mq::shmem
|
namespace fair::mq::shmem
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user