Skip to content

Commit 22de06e

Browse files
committed
Remove memory leaks
Signed-off-by: ahcorde <ahcorde@gmail.com>
1 parent 471c398 commit 22de06e

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

include/class_loader/class_loader.hpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class ClassLoader
169169
template<class Base>
170170
Base * createUnmanagedInstance(const std::string & derived_class_name)
171171
{
172+
class_loader_ref_count--;
172173
return createRawInstance<Base>(derived_class_name, false);
173174
}
174175

@@ -252,6 +253,15 @@ class ClassLoader
252253
CLASS_LOADER_PUBLIC
253254
int unloadLibrary();
254255

256+
void removeWhenPosible()
257+
{
258+
this->remove_when_possible = true;
259+
if (class_loader_ref_count == 0) {
260+
unloadLibraryInternal(false);
261+
delete this;
262+
}
263+
}
264+
255265
private:
256266
/**
257267
* @brief Callback method when a plugin created by this class loader is destroyed
@@ -271,9 +281,15 @@ class ClassLoader
271281
delete (obj);
272282
assert(plugin_ref_count_ > 0);
273283
--plugin_ref_count_;
274-
if (plugin_ref_count_ == 0 && isOnDemandLoadUnloadEnabled()) {
284+
--class_loader_ref_count;
285+
if (plugin_ref_count_ <= 0 && isOnDemandLoadUnloadEnabled()) {
275286
if (!ClassLoader::hasUnmanagedInstanceBeenCreated()) {
276-
unloadLibraryInternal(false);
287+
if (class_loader_ref_count == 0) {
288+
unloadLibraryInternal(false);
289+
}
290+
if (remove_when_possible) {
291+
delete this;
292+
}
277293
} else {
278294
CONSOLE_BRIDGE_logWarn(
279295
"class_loader::ClassLoader: "
@@ -331,7 +347,7 @@ class ClassLoader
331347
std::lock_guard<std::recursive_mutex> lock(plugin_ref_count_mutex_);
332348
++plugin_ref_count_;
333349
}
334-
350+
class_loader_ref_count++;
335351
return obj;
336352
}
337353

@@ -365,6 +381,8 @@ class ClassLoader
365381
int plugin_ref_count_;
366382
std::recursive_mutex plugin_ref_count_mutex_;
367383
static bool has_unmananged_instance_been_created_;
384+
unsigned int class_loader_ref_count;
385+
bool remove_when_possible;
368386
};
369387

370388
} // namespace class_loader

src/class_loader.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ ClassLoader::ClassLoader(const std::string & library_path, bool ondemand_load_un
5555
: ondemand_load_unload_(ondemand_load_unload),
5656
library_path_(library_path),
5757
load_ref_count_(0),
58-
plugin_ref_count_(0)
58+
plugin_ref_count_(0),
59+
class_loader_ref_count(0),
60+
remove_when_possible(false)
5961
{
6062
CONSOLE_BRIDGE_logDebug(
6163
"class_loader.ClassLoader: "

src/class_loader_core.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ void unloadLibrary(const std::string & library_path, ClassLoader * loader)
545545
", keeping library %s open.",
546546
library_path.c_str());
547547
}
548+
purgeGraveyardOfMetaobjects(library_path, loader, true);
548549
return;
549550
} catch (const std::runtime_error & e) {
550551
throw class_loader::LibraryUnloadException(

src/meta_object.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ AbstractMetaObjectBase::~AbstractMetaObjectBase()
7171
"class_loader.impl.AbstractMetaObjectBase: "
7272
"Destroying MetaObject %p (base = %s, derived = %s, library path = %s)",
7373
this, baseClassName().c_str(), className().c_str(), getAssociatedLibraryPath().c_str());
74+
for (unsigned int i = 0; i < impl_->associated_class_loaders_.size(); i++) {
75+
delete impl_->associated_class_loaders_[i];
76+
}
7477
delete impl_;
7578
}
7679

src/multi_library_class_loader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ MultiLibraryClassLoader::MultiLibraryClassLoader(bool enable_ondemand_loadunload
5454
MultiLibraryClassLoader::~MultiLibraryClassLoader()
5555
{
5656
shutdownAllClassLoaders();
57+
for (auto & loader : impl_->active_class_loaders_) {
58+
if (loader.second) {
59+
loader.second->removeWhenPosible();
60+
}
61+
}
5762
delete impl_;
5863
}
5964

0 commit comments

Comments
 (0)