Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix factory map leak (#131) #179

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/class_loader/meta_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class CLASS_LOADER_PUBLIC AbstractMetaObjectBase
* TEMPLATE SUBCLASSES, OTHERWISE THEY WILL PULL IN A REDUNDANT METAOBJECT
* DESTRUCTOR OUTSIDE OF libclass_loader WITHIN THE PLUGIN LIBRARY! T
*/
~AbstractMetaObjectBase();
virtual ~AbstractMetaObjectBase();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@y-okumura-isp meta: the comment is rather imprecise. Lacking virtual indeed breaks polymorphic destruction.


/**
* @brief Gets the literal name of the class.
Expand Down
22 changes: 20 additions & 2 deletions src/class_loader_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,26 @@ std::recursive_mutex & getPluginBaseToFactoryMapMapMutex()

BaseToFactoryMapMap & getGlobalPluginBaseToFactoryMapMap()
{
static BaseToFactoryMapMap instance;
return instance;

static std::shared_ptr<BaseToFactoryMapMap> instance;

// TODO: need lock?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@y-okumura-isp perhaps, static initialization is not thread-safe either.

// TODO: we may use unique_ptr but use shared_ptr for PoC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@y-okumura-isp std::unique_ptr sounds best. Also, the custom deleter is fine, using std::unique_ptr<MetaObject> values would be best.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for comment.
I intended to make changes minimum. But it looks better to hold smart pointer directory.

I have one confirmation.

std::unique_ptr values would be best.

What you say is to change

typedef std::map<ClassName, impl::AbstractMetaObjectBase *> FactoryMap;

to

typedef std::map<ClassName, std::unique_ptr<impl::AbstractMetaObjectBase>> FactoryMap;

Right?

The pointer FactoryMap[class] is used in createInstance, so we could shared_ptr.

typedef std::map<ClassName, std::shared_ptr<impl::AbstractMetaObjectBase>> FactoryMap;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right?

Correct.

The pointer FactoryMap[class] is used in createInstance, so we could shared_ptr.

I presume you mean

factory = dynamic_cast<impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]);
. If so, I see no need for shared ownership. Just grab the raw pointer momentarily.

if(instance == nullptr) {
instance = std::shared_ptr<BaseToFactoryMapMap>(
new BaseToFactoryMapMap,
[](BaseToFactoryMapMap *p) mutable
{
for(auto it_map: *p) {
for(auto it: it_map.second) {
if(it.second) {
delete(it.second);
}
}
}
});
}
return *instance;
}

FactoryMap & getFactoryMapForBaseClass(const std::string & typeid_base_class_name)
Expand Down