}
#endif
}
- int register_dencoders() {
+ int register_dencoders(DencoderRegistry& registry) {
assert(mod);
- using register_dencoders_t = void (*)();
- const auto register_dencoders =
+ using register_dencoders_t = void (*)(DencoderRegistry&);
+ const auto do_register =
reinterpret_cast<register_dencoders_t>(dlsym(mod, REGISTER_DENCODERS_FUNCTION.data()));
- if (register_dencoders == nullptr) {
+ if (do_register == nullptr) {
std::cerr << "failed to dlsym(" << REGISTER_DENCODERS_FUNCTION << ")" << std::endl;
return -1;
}
- const unsigned nr_before = DencoderRegistry::instance().get().size();
- register_dencoders();
- const unsigned nr_after = DencoderRegistry::instance().get().size();
+ const unsigned nr_before = registry.get().size();
+ do_register(registry);
+ const unsigned nr_after = registry.get().size();
return nr_after - nr_before;
}
bool good() const {
void *mod = nullptr;
};
-vector<DencoderPlugin> load_plugins()
+vector<DencoderPlugin> load_plugins(DencoderRegistry& registry)
{
fs::path mod_dir{CEPH_DENC_MOD_DIR};
if (auto ceph_lib = getenv("CEPH_LIB"); ceph_lib) {
if (!plugin.good()) {
continue;
}
- int n = plugin.register_dencoders();
+ int n = plugin.register_dencoders(registry);
if (n <= 0) {
std::cerr << "fail to load dencoders from " << entry << std::endl;
continue;
int main(int argc, const char **argv)
{
- auto plugins = load_plugins();
- auto& dencoders = DencoderRegistry::instance().get();
+ DencoderRegistry registry;
+ auto plugins = load_plugins(registry);
vector<const char*> args;
argv_to_vec(argc, argv, args);
class DencoderRegistry
{
using dencoders_t = std::map<std::string, std::unique_ptr<Dencoder>>;
+
public:
- void add(const char* name, std::unique_ptr<Dencoder>&& denc);
dencoders_t& get() {
return dencoders;
}
- static DencoderRegistry& instance();
+
+ template<typename DencoderT, typename...Args>
+ void emplace(const char* name, Args&&...args) {
+ auto dencoder = std::make_unique<DencoderT>(std::forward<Args>(args)...);
+ dencoders.emplace(name, std::move(dencoder));
+ }
+
private:
dencoders_t dencoders;
};
-template<typename DencoderT, typename...Args>
-void make_and_register_dencoder(const char* name, Args&&...args)
-{
- auto dencoder = std::make_unique<DencoderT>(std::forward<Args>(args)...);
- DencoderRegistry::instance().add(name, std::move(dencoder));
-}
-
-#define TYPE(t) make_and_register_dencoder<DencoderImplNoFeature<t>>(#t, false, false);
-#define TYPE_STRAYDATA(t) make_and_register_dencoder<DencoderImplNoFeature<t>>(#t, true, false);
-#define TYPE_NONDETERMINISTIC(t) make_and_register_dencoder<DencoderImplNoFeature<t>>(#t, false, true);
-#define TYPE_FEATUREFUL(t) make_and_register_dencoder<DencoderImplFeatureful<t>>(#t, false, false);
-#define TYPE_FEATUREFUL_STRAYDATA(t) make_and_register_dencoder<DencoderImplFeatureful<t>>(#t, true, false);
-#define TYPE_FEATUREFUL_NONDETERMINISTIC(t) make_and_register_dencoder<DencoderImplFeatureful<t>>(#t, false, true);
-#define TYPE_FEATUREFUL_NOCOPY(t) make_and_register_dencoder<DencoderImplFeaturefulNoCopy<t>>(#t, false, false);
-#define TYPE_NOCOPY(t) make_and_register_dencoder<DencoderImplNoFeatureNoCopy<t>>(#t, false, false);
-#define MESSAGE(t) make_and_register_dencoder<MessageDencoderImpl<t>>(#t);
+#define TYPE(t) registry.emplace<DencoderImplNoFeature<t>>(#t, false, false);
+#define TYPE_STRAYDATA(t) registry.emplace<DencoderImplNoFeature<t>>(#t, true, false);
+#define TYPE_NONDETERMINISTIC(t) registry.emplace<DencoderImplNoFeature<t>>(#t, false, true);
+#define TYPE_FEATUREFUL(t) registry.emplace<DencoderImplFeatureful<t>>(#t, false, false);
+#define TYPE_FEATUREFUL_STRAYDATA(t) registry.emplace<DencoderImplFeatureful<t>>(#t, true, false);
+#define TYPE_FEATUREFUL_NONDETERMINISTIC(t) registry.emplace<DencoderImplFeatureful<t>>(#t, false, true);
+#define TYPE_FEATUREFUL_NOCOPY(t) registry.emplace<DencoderImplFeaturefulNoCopy<t>>(#t, false, false);
+#define TYPE_NOCOPY(t) registry.emplace<DencoderImplNoFeatureNoCopy<t>>(#t, false, false);
+#define MESSAGE(t) registry.emplace<MessageDencoderImpl<t>>(#t);
#define DENC_API extern "C" [[gnu::visibility("default")]]