]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/ceph-dencoder/denc_plugin.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / tools / ceph-dencoder / denc_plugin.h
CommitLineData
20effc67
TL
1#include <dlfcn.h>
2#include <filesystem>
3#include <vector>
4
5#include "denc_registry.h"
6
7namespace fs = std::filesystem;
8
9class DencoderPlugin {
10 using dencoders_t = std::vector<std::pair<std::string, Dencoder*>>;
11public:
12 DencoderPlugin(const fs::path& path) {
13 mod = dlopen(path.c_str(), RTLD_NOW);
14 if (mod == nullptr) {
15 std::cerr << "failed to dlopen(" << path << "): " << dlerror() << std::endl;
16 }
17 }
18 DencoderPlugin(DencoderPlugin&& other)
19 : mod{other.mod},
20 dencoders{std::move(other.dencoders)}
21 {
22 other.mod = nullptr;
23 other.dencoders.clear();
24 }
25 ~DencoderPlugin() {
26#if !defined(__FreeBSD__)
27 if (mod) {
28 dlclose(mod);
29 }
30#endif
31 }
32 const dencoders_t& register_dencoders() {
33 static constexpr std::string_view REGISTER_DENCODERS_FUNCTION = "register_dencoders\0";
34
35 assert(mod);
36 using register_dencoders_t = void (*)(DencoderPlugin*);
37 const auto do_register =
38 reinterpret_cast<register_dencoders_t>(dlsym(mod, REGISTER_DENCODERS_FUNCTION.data()));
39 if (do_register == nullptr) {
40 std::cerr << "failed to dlsym(" << REGISTER_DENCODERS_FUNCTION << "): "
41 << dlerror() << std::endl;
42 return dencoders;
43 }
44 do_register(this);
45 return dencoders;
46 }
47
48 bool good() const {
49 return mod != nullptr;
50 }
51
52 void unregister_dencoders() {
53 while (!dencoders.empty()) {
54 delete dencoders.back().second;
55 dencoders.pop_back();
56 }
57 }
58 template<typename DencoderT, typename...Args>
59 void emplace(const char* name, Args&&...args) {
60 dencoders.emplace_back(name, new DencoderT(std::forward<Args>(args)...));
61 }
62
63private:
64 void *mod = nullptr;
65 dencoders_t dencoders;
66};
67
68#define TYPE(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, false, false);
69#define TYPE_STRAYDATA(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, true, false);
70#define TYPE_NONDETERMINISTIC(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, false, true);
71#define TYPE_FEATUREFUL(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, false, false);
72#define TYPE_FEATUREFUL_STRAYDATA(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, true, false);
73#define TYPE_FEATUREFUL_NONDETERMINISTIC(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, false, true);
74#define TYPE_FEATUREFUL_NOCOPY(t) plugin->emplace<DencoderImplFeaturefulNoCopy<t>>(#t, false, false);
75#define TYPE_NOCOPY(t) plugin->emplace<DencoderImplNoFeatureNoCopy<t>>(#t, false, false);
76#define MESSAGE(t) plugin->emplace<MessageDencoderImpl<t>>(#t);
77
78#define DENC_API extern "C" [[gnu::visibility("default")]]