Source · fairmq/shmem/
TransportFactory.hpublic header
Defines class fair::mq::shmem::TransportFactory.
Described in How shared memory works, Out-of-band buffers, Tune and debug.
1/********************************************************************************2 * Copyright (C) 2016-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *3 * *4 * This software is distributed under the terms of the *5 * GNU Lesser General Public Licence (LGPL) version 3, *6 * copied verbatim in the file "LICENSE" *7 ********************************************************************************/8 9#ifndef FAIR_MQ_SHMEM_TRANSPORTFACTORY_H_10#define FAIR_MQ_SHMEM_TRANSPORTFACTORY_H_11 12#include "Common.h"13#include "Manager.h"14#include "Message.h"15#include "Poller.h"16#include "Socket.h"17#include "UnmanagedRegionImpl.h"18#include <fairmq/ProgOptions.h>19#include <fairmq/tools/Strings.h>20#include <fairmq/TransportFactory.h>21 22#include <fairlogger/Logger.h>23 24#include <boost/version.hpp>25 26#include <zmq.h>27 28#include <memory> // unique_ptr, make_unique29#include <string>30#include <vector>31#include <stdexcept>32 33namespace fair::mq::shmem34{35 36class TransportFactory final : public fair::mq::TransportFactory37{38 public:39 TransportFactory(const std::string& deviceId = "", const ProgOptions* config = nullptr)40 : fair::mq::TransportFactory(deviceId)41 , fZmqCtx(zmq_ctx_new())42 , fManager(nullptr)43 {44 int major = 0, minor = 0, patch = 0;45 zmq_version(&major, &minor, &patch);46 LOG(debug) << "Transport: Using ZeroMQ (" << major << "." << minor << "." << patch << ") & "47 << "boost::interprocess (" << (BOOST_VERSION / 100000) << "." << (BOOST_VERSION / 100 % 1000) << "." << (BOOST_VERSION % 100) << ")";48 49 if (!fZmqCtx) {50 throw std::runtime_error(tools::ToString("failed creating context, reason: ", zmq_strerror(errno)));51 }52 53 int numIoThreads = 1;54 std::string sessionName = "default";55 size_t segmentSize = 2ULL << 30;56 std::string allocationAlgorithm("rbtree_best_fit");57 if (config) {58 numIoThreads = config->GetProperty<int>("io-threads", numIoThreads);59 sessionName = config->GetProperty<std::string>("session", sessionName);60 segmentSize = config->GetProperty<size_t>("shm-segment-size", segmentSize);61 allocationAlgorithm = config->GetProperty<std::string>("shm-allocation", allocationAlgorithm);62 } else {63 LOG(debug) << "ProgOptions not available! Using defaults.";64 }65 66 if (allocationAlgorithm != "rbtree_best_fit" && allocationAlgorithm != "simple_seq_fit") {67 LOG(error) << "Provided shared memory allocation algorithm '" << allocationAlgorithm << "' is not supported. Supported are 'rbtree_best_fit'/'simple_seq_fit'";68 throw SharedMemoryError(tools::ToString("Provided shared memory allocation algorithm '", allocationAlgorithm, "' is not supported. Supported are 'rbtree_best_fit'/'simple_seq_fit'"));69 }70 71 try {72 if (zmq_ctx_set(fZmqCtx, ZMQ_IO_THREADS, numIoThreads) != 0) {73 LOG(error) << "failed configuring context, reason: " << zmq_strerror(errno);74 }75 76 // Set the maximum number of allowed sockets on the context.77 if (zmq_ctx_set(fZmqCtx, ZMQ_MAX_SOCKETS, 10000) != 0) {78 LOG(error) << "failed configuring context, reason: " << zmq_strerror(errno);79 }80 81 fManager = std::make_unique<Manager>(sessionName, segmentSize, config);82 } catch (boost::interprocess::interprocess_exception& e) {83 LOG(error) << "Could not initialize shared memory transport: " << e.what();84 throw std::runtime_error(tools::ToString("Could not initialize shared memory transport: ", e.what()));85 } catch (const std::exception& e) {86 LOG(error) << "Could not initialize shared memory transport: " << e.what();87 throw std::runtime_error(tools::ToString("Could not initialize shared memory transport: ", e.what()));88 }89 }90 91 TransportFactory(const TransportFactory&) = delete;92 TransportFactory(TransportFactory&&) = delete;93 TransportFactory& operator=(const TransportFactory&) = delete;94 TransportFactory& operator=(TransportFactory&&) = delete;95 96 MessagePtr CreateMessage() override97 {98 return std::make_unique<Message>(*fManager, this);99 }100 101 MessagePtr CreateMessage(Alignment alignment) override102 {103 return std::make_unique<Message>(*fManager, alignment, this);104 }105 106 MessagePtr CreateMessage(size_t size) override107 {108 return std::make_unique<Message>(*fManager, size, this);109 }110 111 MessagePtr CreateMessage(size_t size, Alignment alignment) override112 {113 return std::make_unique<Message>(*fManager, size, alignment, this);114 }115 116 MessagePtr CreateMessage(void* data, size_t size, fair::mq::FreeFn* ffn, void* hint = nullptr) override117 {118 return std::make_unique<Message>(*fManager, data, size, ffn, hint, this);119 }120 121 MessagePtr CreateMessage(UnmanagedRegionPtr& region,122 void* data,123 size_t size,124 void* hint = nullptr) override125 {126 return std::make_unique<Message>(*fManager, region, data, size, hint, this);127 }128 129 SocketPtr CreateSocket(const std::string& type, const std::string& name) override130 {131 return std::make_unique<Socket>(*fManager, type, name, GetId(), fZmqCtx, this);132 }133 134 PollerPtr CreatePoller(const std::vector<Channel>& channels) const override135 {136 return std::make_unique<Poller>(channels);137 }138 139 PollerPtr CreatePoller(const std::vector<Channel*>& channels) const override140 {141 return std::make_unique<Poller>(channels);142 }143 144 PollerPtr CreatePoller(const std::unordered_map<std::string, std::vector<Channel>>& channelsMap, const std::vector<std::string>& channelList) const override145 {146 return std::make_unique<Poller>(channelsMap, channelList);147 }148 149 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) override150 {151 cfg.path = path;152 cfg.creationFlags = flags;153 return CreateUnmanagedRegion(size, callback, nullptr, std::move(cfg));154 }155 156 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionBulkCallback bulkCallback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) override157 {158 cfg.path = path;159 cfg.creationFlags = flags;160 return CreateUnmanagedRegion(size, nullptr, bulkCallback, std::move(cfg));161 }162 163 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, int64_t userFlags, RegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) override164 {165 cfg.path = path;166 cfg.userFlags = userFlags;167 cfg.creationFlags = flags;168 return CreateUnmanagedRegion(size, callback, nullptr, std::move(cfg));169 }170 171 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, int64_t userFlags, RegionBulkCallback bulkCallback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) override172 {173 cfg.path = path;174 cfg.userFlags = userFlags;175 cfg.creationFlags = flags;176 return CreateUnmanagedRegion(size, nullptr, bulkCallback, std::move(cfg));177 }178 179 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg) override180 {181 return CreateUnmanagedRegion(size, callback, nullptr, std::move(cfg));182 }183 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionBulkCallback bulkCallback, RegionConfig cfg) override184 {185 return CreateUnmanagedRegion(size, nullptr, bulkCallback, std::move(cfg));186 }187 188 UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionBulkCallback bulkCallback, fair::mq::RegionConfig cfg)189 {190 return std::make_unique<UnmanagedRegionImpl>(*fManager, size, callback, bulkCallback, std::move(cfg), this);191 }192 193 void SubscribeToRegionEvents(RegionEventCallback callback) override { fManager->SubscribeToRegionEvents(callback); }194 bool SubscribedToRegionEvents() override { return fManager->SubscribedToRegionEvents(); }195 void UnsubscribeFromRegionEvents() override { fManager->UnsubscribeFromRegionEvents(); }196 std::vector<fair::mq::RegionInfo> GetRegionInfo() override { return fManager->GetRegionInfo(); }197 198 Transport GetType() const override { return fair::mq::Transport::SHM; }199 200 void Interrupt() override { fManager->Interrupt(); }201 void Resume() override { fManager->Resume(); }202 void Reset() override { fManager->Reset(); }203 204 char* GetDataAddressFromHandle(const MetaHeader& meta) { return fManager->GetDataAddressFromHandle(meta); }205 206 ~TransportFactory() override207 {208 LOG(debug) << "Destroying Shared Memory transport...";209 210 if (fZmqCtx) {211 while (true) {212 if (zmq_ctx_term(fZmqCtx) != 0) {213 if (errno == EINTR) {214 LOG(debug) << "zmq_ctx_term interrupted by system call, retrying";215 continue;216 } else {217 fZmqCtx = nullptr;218 }219 }220 break;221 }222 } else {223 LOG(error) << "context not available for shutdown";224 }225 }226 227 private:228 void* fZmqCtx;229 std::unique_ptr<Manager> fManager;230};231 232} // namespace fair::mq::shmem233 234#endif /* FAIR_MQ_SHMEM_TRANSPORTFACTORY_H_ */