mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 10:12:39 +01:00
ircd::mods: Add sym_ptr/sym_ref to link symbols with a typed object.
This commit is contained in:
parent
a8fc400130
commit
6a0e5e4de5
3 changed files with 118 additions and 5 deletions
|
@ -41,6 +41,8 @@ using mapi::version_t;
|
||||||
IRCD_EXCEPTION(ircd::error, error)
|
IRCD_EXCEPTION(ircd::error, error)
|
||||||
IRCD_EXCEPTION(error, filesystem_error)
|
IRCD_EXCEPTION(error, filesystem_error)
|
||||||
IRCD_EXCEPTION(error, invalid_export)
|
IRCD_EXCEPTION(error, invalid_export)
|
||||||
|
IRCD_EXCEPTION(error, expired_symbol)
|
||||||
|
IRCD_EXCEPTION(error, undefined_symbol)
|
||||||
|
|
||||||
extern struct log::log log;
|
extern struct log::log log;
|
||||||
|
|
||||||
|
@ -80,6 +82,38 @@ struct module
|
||||||
template<> const uint8_t *module::ptr<const uint8_t>(const std::string &name) const;
|
template<> const uint8_t *module::ptr<const uint8_t>(const std::string &name) const;
|
||||||
template<> uint8_t *module::ptr<uint8_t>(const std::string &name);
|
template<> uint8_t *module::ptr<uint8_t>(const std::string &name);
|
||||||
|
|
||||||
|
class sym_ptr
|
||||||
|
:std::weak_ptr<mod>
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
operator bool() const { return !expired(); }
|
||||||
|
bool operator!() const { return expired(); }
|
||||||
|
|
||||||
|
template<class T> const T *get() const;
|
||||||
|
template<class T> T *get();
|
||||||
|
|
||||||
|
template<class T> const T *operator->() const;
|
||||||
|
template<class T> T *operator->();
|
||||||
|
|
||||||
|
template<class T> const T &operator*() const;
|
||||||
|
template<class T> T &operator*();
|
||||||
|
|
||||||
|
sym_ptr(const std::string &modname, const std::string &symname);
|
||||||
|
~sym_ptr() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct sym_ref
|
||||||
|
:protected sym_ptr
|
||||||
|
{
|
||||||
|
operator const T &() const { return sym_ptr::operator*<T>(); }
|
||||||
|
operator T &() { return sym_ptr::operator*<T>(); }
|
||||||
|
|
||||||
|
using sym_ptr::sym_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<std::string> symbols(const std::string &fullpath, const std::string §ion);
|
std::vector<std::string> symbols(const std::string &fullpath, const std::string §ion);
|
||||||
std::vector<std::string> symbols(const std::string &fullpath);
|
std::vector<std::string> symbols(const std::string &fullpath);
|
||||||
std::vector<std::string> sections(const std::string &fullpath);
|
std::vector<std::string> sections(const std::string &fullpath);
|
||||||
|
@ -114,6 +148,57 @@ using mods::module; // Bring struct module into mai
|
||||||
|
|
||||||
} // namespace ircd
|
} // namespace ircd
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T &
|
||||||
|
ircd::mods::sym_ptr::operator*()
|
||||||
|
{
|
||||||
|
if(unlikely(expired()))
|
||||||
|
throw expired_symbol("The reference to a symbol in another module is no longer valid");
|
||||||
|
|
||||||
|
return *get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T *
|
||||||
|
ircd::mods::sym_ptr::operator->()
|
||||||
|
{
|
||||||
|
return get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T *
|
||||||
|
ircd::mods::sym_ptr::get()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T *>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const T &
|
||||||
|
ircd::mods::sym_ptr::operator*()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if(unlikely(expired()))
|
||||||
|
throw expired_symbol("The const reference to a symbol in another module is no longer valid");
|
||||||
|
|
||||||
|
return *get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const T *
|
||||||
|
ircd::mods::sym_ptr::operator->()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const T *
|
||||||
|
ircd::mods::sym_ptr::get()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const T *>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T &
|
T &
|
||||||
ircd::mods::module::get(const std::string &name)
|
ircd::mods::module::get(const std::string &name)
|
||||||
|
|
|
@ -105,8 +105,8 @@ try
|
||||||
|
|
||||||
module listener("listen.so");
|
module listener("listen.so");
|
||||||
module client_versions("client_versions.so");
|
module client_versions("client_versions.so");
|
||||||
module client_login("client_login.so");
|
|
||||||
module client_register("client_register.so");
|
module client_register("client_register.so");
|
||||||
|
module client_login("client_login.so");
|
||||||
|
|
||||||
// This is the main program loop. Right now all it does is sleep until notified
|
// This is the main program loop. Right now all it does is sleep until notified
|
||||||
// to shutdown, but it can do other things eventually. Other subsystems may have
|
// to shutdown, but it can do other things eventually. Other subsystems may have
|
||||||
|
|
36
ircd/mods.cc
36
ircd/mods.cc
|
@ -174,8 +174,8 @@ const
|
||||||
template<> uint8_t *
|
template<> uint8_t *
|
||||||
ircd::mods::module::ptr<uint8_t>(const std::string &name)
|
ircd::mods::module::ptr<uint8_t>(const std::string &name)
|
||||||
{
|
{
|
||||||
const auto &mod(**this);
|
auto &mod(**this);
|
||||||
return &mod.handle.get<uint8_t>(name);
|
return mod.ptr<uint8_t>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -184,7 +184,7 @@ ircd::mods::module::ptr<const uint8_t>(const std::string &name)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
const auto &mod(**this);
|
const auto &mod(**this);
|
||||||
return &mod.handle.get<const uint8_t>(name);
|
return mod.ptr<const uint8_t>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -195,7 +195,35 @@ const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto &mod(**this);
|
const auto &mod(**this);
|
||||||
return mod.handle.has(name);
|
return mod.has(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// sym_ptr
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::mods::sym_ptr::sym_ptr(const std::string &modname,
|
||||||
|
const std::string &symname)
|
||||||
|
:std::weak_ptr<mod>
|
||||||
|
{
|
||||||
|
module(modname)
|
||||||
|
}
|
||||||
|
,ptr{[this, &modname, &symname]
|
||||||
|
{
|
||||||
|
const life_guard<mods::mod> mod(*this);
|
||||||
|
|
||||||
|
if(unlikely(!mod->has(symname)))
|
||||||
|
throw undefined_symbol("Could not find symbol '%s' in module '%s'", symname, mod->name());
|
||||||
|
|
||||||
|
return mod->ptr(symname);
|
||||||
|
}()}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::mods::sym_ptr::~sym_ptr()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in a new issue