Skip to content

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.

fairmq/shmem/TransportFactory.h234 lines · C++API: TransportFactoryGitHub ↗
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_ */