Use shared_ptr to store plugins (#1640)
This commit is contained in:
parent
44b6916d7e
commit
586fd6d67a
|
@ -18,7 +18,7 @@ int main()
|
|||
{
|
||||
auto client = HttpClient::newHttpClient("http://www.baidu.com");
|
||||
client->setSockOptCallback([](int fd) {
|
||||
std::cout << "setSockOptCallback" << std::endl;
|
||||
std::cout << "setSockOptCallback:" << fd << std::endl;
|
||||
#ifdef __linux__
|
||||
int optval = 10;
|
||||
::setsockopt(fd,
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace drogon
|
|||
{
|
||||
class DrObjectBase;
|
||||
using DrAllocFunc = std::function<DrObjectBase *()>;
|
||||
using DrSharedAllocFunc = std::function<std::shared_ptr<DrObjectBase>()>;
|
||||
|
||||
/**
|
||||
* @brief A map class which can create DrObjects from names.
|
||||
|
@ -47,7 +48,8 @@ class DROGON_EXPORT DrClassMap
|
|||
* @param func The function which can create a new instance of the class.
|
||||
*/
|
||||
static void registerClass(const std::string &className,
|
||||
const DrAllocFunc &func);
|
||||
const DrAllocFunc &func,
|
||||
const DrSharedAllocFunc &sharedFunc = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Create a new instance of the class named by className
|
||||
|
@ -57,6 +59,12 @@ class DROGON_EXPORT DrClassMap
|
|||
*/
|
||||
static DrObjectBase *newObject(const std::string &className);
|
||||
|
||||
/**
|
||||
* @brief Get the shared_ptr instance of the class named by className
|
||||
*/
|
||||
static std::shared_ptr<DrObjectBase> newSharedObject(
|
||||
const std::string &className);
|
||||
|
||||
/**
|
||||
* @brief Get the singleton object of the class named by className
|
||||
*
|
||||
|
@ -129,7 +137,8 @@ class DROGON_EXPORT DrClassMap
|
|||
}
|
||||
|
||||
protected:
|
||||
static std::unordered_map<std::string, DrAllocFunc> &getMap();
|
||||
static std::unordered_map<std::string,
|
||||
std::pair<DrAllocFunc, DrSharedAllocFunc>>
|
||||
&getMap();
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
|
|
@ -102,8 +102,12 @@ class DrObject : public virtual DrObjectBase
|
|||
void>::type
|
||||
registerClass()
|
||||
{
|
||||
DrClassMap::registerClass(className(),
|
||||
[]() -> DrObjectBase * { return new T; });
|
||||
DrClassMap::registerClass(
|
||||
className(),
|
||||
[]() -> DrObjectBase * { return new T; },
|
||||
[]() -> std::shared_ptr<DrObjectBase> {
|
||||
return std::make_shared<T>();
|
||||
});
|
||||
}
|
||||
template <typename D>
|
||||
typename std::enable_if<!std::is_default_constructible<D>::value,
|
||||
|
|
|
@ -199,7 +199,26 @@ class DROGON_EXPORT HttpAppFramework : public trantor::NonCopyable
|
|||
return pluginPtr;
|
||||
}
|
||||
|
||||
/// Get the plugin object registered in the framework
|
||||
/// Get the shared_ptr plugin object registered in the framework
|
||||
/**
|
||||
* @note
|
||||
* This method is usually called after the framework runs.
|
||||
* Calling this method in the initAndStart() method of plugins is also
|
||||
* valid.
|
||||
*/
|
||||
template <typename T>
|
||||
std::shared_ptr<T> getSharedPlugin()
|
||||
{
|
||||
static_assert(IsPlugin<T>::value,
|
||||
"The Template parameter must be a subclass of "
|
||||
"PluginBase");
|
||||
assert(isRunning());
|
||||
static auto pluginPtr =
|
||||
std::dynamic_pointer_cast<T>(getSharedPlugin(T::classTypeName()));
|
||||
return pluginPtr;
|
||||
}
|
||||
|
||||
/// @brief the plugin object registered in the framework
|
||||
/**
|
||||
* @param name is the class name of the plugin.
|
||||
*
|
||||
|
@ -210,6 +229,17 @@ class DROGON_EXPORT HttpAppFramework : public trantor::NonCopyable
|
|||
*/
|
||||
virtual PluginBase *getPlugin(const std::string &name) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the shared_ptr plugin object registered in the framework
|
||||
*
|
||||
* @note
|
||||
* This method is usually called after the framework runs.
|
||||
* Calling this method in the initAndStart() method of plugins is also
|
||||
* valid.
|
||||
*/
|
||||
virtual std::shared_ptr<PluginBase> getSharedPlugin(
|
||||
const std::string &name) = 0;
|
||||
|
||||
/* The following is a series of methods of AOP */
|
||||
|
||||
/// Register a beginning advice
|
||||
|
|
|
@ -39,7 +39,9 @@ class DROGON_EXPORT GlobalFilters
|
|||
public std::enable_shared_from_this<GlobalFilters>
|
||||
{
|
||||
public:
|
||||
GlobalFilters() = default;
|
||||
GlobalFilters()
|
||||
{
|
||||
}
|
||||
void initAndStart(const Json::Value &config) override;
|
||||
void shutdown() override;
|
||||
|
||||
|
@ -49,4 +51,4 @@ class DROGON_EXPORT GlobalFilters
|
|||
bool regexFlag_{false};
|
||||
};
|
||||
} // namespace plugin
|
||||
} // namespace drogon
|
||||
} // namespace drogon
|
||||
|
|
|
@ -40,10 +40,12 @@ static std::mutex &getMapMutex()
|
|||
} // namespace drogon
|
||||
|
||||
void DrClassMap::registerClass(const std::string &className,
|
||||
const DrAllocFunc &func)
|
||||
const DrAllocFunc &func,
|
||||
const DrSharedAllocFunc &sharedFunc)
|
||||
{
|
||||
LOG_TRACE << "Register class:" << className;
|
||||
getMap().insert(std::make_pair(className, func));
|
||||
getMap().insert(
|
||||
std::make_pair(className, std::make_pair(func, sharedFunc)));
|
||||
}
|
||||
|
||||
DrObjectBase *DrClassMap::newObject(const std::string &className)
|
||||
|
@ -51,12 +53,26 @@ DrObjectBase *DrClassMap::newObject(const std::string &className)
|
|||
auto iter = getMap().find(className);
|
||||
if (iter != getMap().end())
|
||||
{
|
||||
return iter->second();
|
||||
return iter->second.first();
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<DrObjectBase> DrClassMap::newSharedObject(
|
||||
const std::string &className)
|
||||
{
|
||||
auto iter = getMap().find(className);
|
||||
if (iter != getMap().end())
|
||||
{
|
||||
if (iter->second.second)
|
||||
return iter->second.second();
|
||||
else
|
||||
return std::shared_ptr<DrObjectBase>(iter->second.first());
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
const std::shared_ptr<DrObjectBase> &DrClassMap::getSingleInstance(
|
||||
const std::string &className)
|
||||
{
|
||||
|
@ -68,7 +84,7 @@ const std::shared_ptr<DrObjectBase> &DrClassMap::getSingleInstance(
|
|||
if (iter != singleInstanceMap.end())
|
||||
return iter->second;
|
||||
}
|
||||
auto newObj = std::shared_ptr<DrObjectBase>(newObject(className));
|
||||
auto newObj = newSharedObject(className);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
auto ret = singleInstanceMap.insert(
|
||||
|
@ -95,8 +111,11 @@ std::vector<std::string> DrClassMap::getAllClassName()
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, DrAllocFunc> &DrClassMap::getMap()
|
||||
std::unordered_map<std::string, std::pair<DrAllocFunc, DrSharedAllocFunc>>
|
||||
&DrClassMap::getMap()
|
||||
{
|
||||
static std::unordered_map<std::string, DrAllocFunc> map;
|
||||
static std::unordered_map<std::string,
|
||||
std::pair<DrAllocFunc, DrSharedAllocFunc>>
|
||||
map;
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -348,6 +348,12 @@ PluginBase *HttpAppFrameworkImpl::getPlugin(const std::string &name)
|
|||
{
|
||||
return pluginsManagerPtr_->getPlugin(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<PluginBase> HttpAppFrameworkImpl::getSharedPlugin(
|
||||
const std::string &name)
|
||||
{
|
||||
return pluginsManagerPtr_->getSharedPlugin(name);
|
||||
}
|
||||
void HttpAppFrameworkImpl::addPlugin(
|
||||
const std::string &name,
|
||||
const std::vector<std::string> &dependencies,
|
||||
|
|
|
@ -57,6 +57,8 @@ class HttpAppFrameworkImpl final : public HttpAppFramework
|
|||
}
|
||||
|
||||
PluginBase *getPlugin(const std::string &name) override;
|
||||
std::shared_ptr<PluginBase> getSharedPlugin(
|
||||
const std::string &name) override;
|
||||
void addPlugins(const Json::Value &configs);
|
||||
void addPlugin(const std::string &name,
|
||||
const std::vector<std::string> &dependencies,
|
||||
|
|
|
@ -88,16 +88,14 @@ void PluginsManager::initializeAllPlugins(
|
|||
}
|
||||
void PluginsManager::createPlugin(const std::string &pluginName)
|
||||
{
|
||||
auto *p = DrClassMap::newObject(pluginName);
|
||||
auto *pluginPtr = dynamic_cast<PluginBase *>(p);
|
||||
auto pluginPtr = std::dynamic_pointer_cast<PluginBase>(
|
||||
DrClassMap::newSharedObject(pluginName));
|
||||
if (!pluginPtr)
|
||||
{
|
||||
if (p)
|
||||
delete p;
|
||||
LOG_ERROR << "Plugin " << pluginName << " undefined!";
|
||||
return;
|
||||
}
|
||||
pluginsMap_[pluginName].reset(pluginPtr);
|
||||
pluginsMap_[pluginName] = pluginPtr;
|
||||
}
|
||||
PluginBase *PluginsManager::getPlugin(const std::string &pluginName)
|
||||
{
|
||||
|
@ -107,4 +105,15 @@ PluginBase *PluginsManager::getPlugin(const std::string &pluginName)
|
|||
return iter->second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<PluginBase> PluginsManager::getSharedPlugin(
|
||||
const std::string &pluginName)
|
||||
{
|
||||
auto iter = pluginsMap_.find(pluginName);
|
||||
if (iter != pluginsMap_.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
namespace drogon
|
||||
{
|
||||
using PluginBasePtr = std::unique_ptr<PluginBase>;
|
||||
using PluginBasePtr = std::shared_ptr<PluginBase>;
|
||||
|
||||
class PluginsManager : trantor::NonCopyable
|
||||
{
|
||||
|
@ -29,6 +29,8 @@ class PluginsManager : trantor::NonCopyable
|
|||
|
||||
PluginBase *getPlugin(const std::string &pluginName);
|
||||
|
||||
std::shared_ptr<PluginBase> getSharedPlugin(const std::string &pluginName);
|
||||
|
||||
~PluginsManager();
|
||||
|
||||
private:
|
||||
|
|
2
trantor
2
trantor
|
@ -1 +1 @@
|
|||
Subproject commit 60fb0a0577eb06c1725e927c8ef3d549611090c0
|
||||
Subproject commit 8601bb91130f4254f9cc710d80860f4c210c8b58
|
Loading…
Reference in New Issue