summaryrefslogtreecommitdiff
path: root/src/core/managed
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/managed')
-rw-r--r--src/core/managed/Managed.hpp2
-rw-r--r--src/core/managed/Manager.cpp42
-rw-r--r--src/core/managed/Manager.hpp8
3 files changed, 46 insertions, 6 deletions
diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp
index 4784e46..26118dc 100644
--- a/src/core/managed/Managed.hpp
+++ b/src/core/managed/Managed.hpp
@@ -82,7 +82,7 @@ public:
/**
* Virtual destuctor which may be overwritten by child classes.
*/
- virtual ~Managed(){};
+ virtual ~Managed() { mgr.unmanage(this); };
/**
* Returns a reference ot the manager instance which owns this managed
diff --git a/src/core/managed/Manager.cpp b/src/core/managed/Manager.cpp
index ee4da5f..694587f 100644
--- a/src/core/managed/Manager.cpp
+++ b/src/core/managed/Manager.cpp
@@ -123,6 +123,12 @@ Manager::~Manager()
// Perform a final sweep
sweep();
+#ifdef MANAGER_GRAPHVIZ_EXPORT
+ if (!objects.empty()) {
+ exportGraphviz("manager_crashdump.dot");
+ }
+#endif
+
// All objects should have been deleted!
assert(objects.empty());
@@ -159,6 +165,30 @@ void Manager::manage(Managed *o)
nextUid++;
}
+void Manager::unmanage(Managed *o)
+{
+ if (!deleted.count(o)) {
+ Manager::ObjectDescriptor *descr = getDescriptor(o);
+ if (descr != nullptr) {
+ // Make sure all input references are deleted
+ while (!descr->refIn.empty()) {
+ deleteRef(o, descr->refIn.begin()->first, true);
+ }
+ // Remove all output references of this Managed
+ while (!descr->refOut.empty()) {
+ deleteRef(descr->refOut.begin()->first, o, true);
+ }
+
+ // Remove the uid, data and event store entry
+ uids.erase(descr->uid);
+ store.erase(o);
+ events.erase(o);
+ marked.erase(o);
+ objects.erase(o);
+ }
+ }
+}
+
void Manager::addRef(Managed *tar, Managed *src)
{
#ifdef MANAGER_DEBUG_PRINT
@@ -196,10 +226,11 @@ void Manager::deleteRef(Managed *tar, Managed *src, bool all)
#ifdef MANAGER_DEBUG_HIDDEN_ROOTED
if (deletionRecursionDepth > 0 && src == 0) {
- std::cerr << "\x1b[41;30mManager:\x1b[0m A managed object contains a rooted reference, "
+ std::cerr << "\x1b[41;30mManager:\x1b[0m A managed object contains a "
+ "rooted reference, "
"this may cause memory leaks!" << std::endl;
- std::cerr << "\x1b[41;30mManager:\x1b[0m Referenced object is " << tar << " of type "
- << tar->type()->name << std::endl;
+ std::cerr << "\x1b[41;30mManager:\x1b[0m Referenced object is " << tar
+ << " of type " << tar->type()->name << std::endl;
}
#endif
@@ -286,10 +317,10 @@ void Manager::purgeDeleted()
for (size_t i = 0; i < orderedDeleted.size(); i++) {
Managed *m = orderedDeleted[i];
+ delete m;
deleted.erase(m);
marked.erase(m);
objects.erase(m);
- delete m;
}
orderedDeleted.clear();
assert(deleted.empty());
@@ -611,7 +642,8 @@ void Manager::exportGraphviz(const char *filename)
// Print the label
fs << "\t\tlabel=<"
<< "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">"
- << "<TR><TD>" << std::hex << std::showbase << p << "</TD></TR>"
+ << "<TR><TD>" << std::hex << std::showbase << p << " ("
+ << getUid(objectPtr) << ")</TD></TR>"
<< "<TR><TD><I>" << typeName << "</I></TD></TR>";
// Print any name
diff --git a/src/core/managed/Manager.hpp b/src/core/managed/Manager.hpp
index 6275df1..47d1fc7 100644
--- a/src/core/managed/Manager.hpp
+++ b/src/core/managed/Manager.hpp
@@ -273,6 +273,14 @@ public:
void manage(Managed *o);
/**
+ * Removes a previously managed object from the manager -- this function is
+ * called from the destructor of the Managed class.
+ *
+ * @param o is the object that should be unregistered from the manager.
+ */
+ void unmanage(Managed *o);
+
+ /**
* Stores a reference to the given target object from the given source
* object. If the source pointer is set to nullptr, this means that the
* target object is rooted (semantic: it is reachable from the current