out << " is_deterministic exit w/ success if type encodes deterministically\n";
}
-vector<DencoderPlugin> load_plugins(DencoderRegistry& registry)
+vector<DencoderPlugin> load_plugins()
{
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(registry);
- if (n <= 0) {
- std::cerr << "fail to load dencoders from " << entry << std::endl;
- continue;
- }
- std::cout << "load " << n << " from " << entry << std::endl;
dencoder_plugins.push_back(std::move(plugin));
}
return dencoder_plugins;
int main(int argc, const char **argv)
{
+ vector<DencoderPlugin> plugins = load_plugins();
DencoderRegistry registry;
- auto plugins = load_plugins(registry);
+ for (auto& plugin : plugins) {
+ for (auto& [name, denc] : plugin.register_dencoders()) {
+ registry.register_dencoder(name, denc);
+ }
+ }
vector<const char*> args;
argv_to_vec(argc, argv, args);
cerr << "class '" << cname << "' unknown" << std::endl;
return 1;
}
- den = dencoders[cname].get();
+ den = dencoders[cname];
den->generate();
} else if (*i == string("skip")) {
++i;
#undef TYPE_FEATUREFUL_NOCOPY
#undef MESSAGE
-#include "denc_registry.h"
+#include "denc_plugin.h"
-DENC_API void register_dencoders(DencoderRegistry& registry)
+DENC_API void register_dencoders(DencoderPlugin* plugin)
{
#include "common_types.h"
}
+
+DENC_API void unregister_dencoders(DencoderPlugin* plugin)
+{
+ plugin->unregister_dencoders();
+}
#include <dlfcn.h>
#include <filesystem>
+#include <vector>
#include "denc_registry.h"
namespace fs = std::filesystem;
class DencoderPlugin {
+ using dencoders_t = std::vector<std::pair<std::string, Dencoder*>>;
public:
DencoderPlugin(const fs::path& path) {
mod = dlopen(path.c_str(), RTLD_NOW);
std::cerr << "failed to dlopen(" << path << "): " << dlerror() << std::endl;
}
}
+ DencoderPlugin(DencoderPlugin&& other)
+ : mod{other.mod},
+ dencoders{std::move(other.dencoders)}
+ {
+ other.mod = nullptr;
+ other.dencoders.clear();
+ }
~DencoderPlugin() {
#if !defined(__FreeBSD__)
if (mod) {
}
#endif
}
- int register_dencoders(DencoderRegistry& registry) {
+ const dencoders_t& register_dencoders() {
static constexpr string_view REGISTER_DENCODERS_FUNCTION = "register_dencoders\0";
assert(mod);
- using register_dencoders_t = void (*)(DencoderRegistry&);
+ using register_dencoders_t = void (*)(DencoderPlugin*);
const auto do_register =
reinterpret_cast<register_dencoders_t>(dlsym(mod, REGISTER_DENCODERS_FUNCTION.data()));
if (do_register == nullptr) {
- std::cerr << "failed to dlsym(" << REGISTER_DENCODERS_FUNCTION << ")" << std::endl;
- return -1;
+ std::cerr << "failed to dlsym(" << REGISTER_DENCODERS_FUNCTION << "): "
+ << dlerror() << std::endl;
+ return dencoders;
}
- const unsigned nr_before = registry.get().size();
- do_register(registry);
- const unsigned nr_after = registry.get().size();
- return nr_after - nr_before;
+ do_register(this);
+ return dencoders;
}
+
bool good() const {
return mod != nullptr;
}
+
+ void unregister_dencoders() {
+ while (!dencoders.empty()) {
+ delete dencoders.back().second;
+ dencoders.pop_back();
+ }
+ }
+ template<typename DencoderT, typename...Args>
+ void emplace(const char* name, Args&&...args) {
+ dencoders.emplace_back(name, new DencoderT(std::forward<Args>(args)...));
+ }
+
private:
void *mod = nullptr;
+ dencoders_t dencoders;
};
+
+#define TYPE(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, false, false);
+#define TYPE_STRAYDATA(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, true, false);
+#define TYPE_NONDETERMINISTIC(t) plugin->emplace<DencoderImplNoFeature<t>>(#t, false, true);
+#define TYPE_FEATUREFUL(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, false, false);
+#define TYPE_FEATUREFUL_STRAYDATA(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, true, false);
+#define TYPE_FEATUREFUL_NONDETERMINISTIC(t) plugin->emplace<DencoderImplFeatureful<t>>(#t, false, true);
+#define TYPE_FEATUREFUL_NOCOPY(t) plugin->emplace<DencoderImplFeaturefulNoCopy<t>>(#t, false, false);
+#define TYPE_NOCOPY(t) plugin->emplace<DencoderImplNoFeatureNoCopy<t>>(#t, false, false);
+#define MESSAGE(t) plugin->emplace<MessageDencoderImpl<t>>(#t);
+
+#define DENC_API extern "C" [[gnu::visibility("default")]]
#include <iostream>
#include <string>
+#include <string_view>
+
#include "include/buffer_fwd.h"
#include "msg/Message.h"
class DencoderRegistry
{
- using dencoders_t = std::map<std::string, std::unique_ptr<Dencoder>>;
+ using dencoders_t = std::map<std::string_view, Dencoder*>;
public:
dencoders_t& get() {
return dencoders;
}
-
- 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));
+ void register_dencoder(std::string_view name, Dencoder* denc) {
+ dencoders.emplace(name, denc);
}
-
private:
dencoders_t dencoders;
};
-
-#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")]]
#undef TYPE_FEATUREFUL_NOCOPY
#undef MESSAGE
-#include "denc_registry.h"
+#include "denc_plugin.h"
-DENC_API void register_dencoders(DencoderRegistry& registry)
+DENC_API void register_dencoders(DencoderPlugin* plugin)
{
#include "mds_types.h"
}
+
+DENC_API void unregister_dencoders(DencoderPlugin* plugin)
+{
+ plugin->unregister_dencoders();
+}
#undef TYPE_FEATUREFUL_NOCOPY
#undef MESSAGE
-#include "denc_registry.h"
+#include "denc_plugin.h"
// cannot initialize dencoders when initializing static variables, as some of
// the types are allocated using mempool, and the mempools are initialized as
// static variables.
-DENC_API void register_dencoders(DencoderRegistry& registry)
+DENC_API void register_dencoders(DencoderPlugin* plugin)
{
#include "osd_types.h"
}
+
+DENC_API void unregister_dencoders(DencoderPlugin* plugin)
+{
+ plugin->unregister_dencoders();
+}
#undef TYPE_FEATUREFUL_NOCOPY
#undef MESSAGE
-#include "denc_registry.h"
+#include "denc_plugin.h"
-DENC_API void register_dencoders(DencoderRegistry& registry)
+DENC_API void register_dencoders(DencoderPlugin* plugin)
{
#include "rbd_types.h"
}
+
+DENC_API void unregister_dencoders(DencoderPlugin* plugin)
+{
+ plugin->unregister_dencoders();
+}
#undef TYPE_FEATUREFUL_NOCOPY
#undef MESSAGE
-#include "denc_registry.h"
+#include "denc_plugin.h"
-DENC_API void register_dencoders(DencoderRegistry& registry)
+DENC_API void register_dencoders(DencoderPlugin* plugin)
{
#include "rgw_types.h"
}
+
+DENC_API void unregister_dencoders(DencoderPlugin* plugin)
+{
+ plugin->unregister_dencoders();
+}