]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/ceph-dencoder/denc_plugin.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / tools / ceph-dencoder / denc_plugin.h
1 #include <dlfcn.h>
2 #include <filesystem>
3 #include <vector>
4
5 #include "denc_registry.h"
6
7 namespace fs = std::filesystem;
8
9 class DencoderPlugin {
10 using dencoders_t = std::vector<std::pair<std::string, Dencoder*>>;
11 public:
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
63 private:
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")]]