From ed50d684bf212da7a7a01ddb4bc82928f238f56d Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 3 Nov 2014 18:20:58 +0000 Subject: fixed bugs in garbage collector, improved handle classes, added some more unit tests git-svn-id: file:///var/local/svn/basicwriter@97 daaaf23c-2e50-4459-9457-1e69db5a47bf --- src/core/dom/Node.cpp | 20 ++++++++--- src/core/dom/Node.hpp | 92 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 72 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/core/dom/Node.cpp b/src/core/dom/Node.cpp index 8df0787..7c4852a 100644 --- a/src/core/dom/Node.cpp +++ b/src/core/dom/Node.cpp @@ -187,7 +187,6 @@ void NodeManager::addRef(Node *tar, Node *src) // Store the tar <- src reference assert(dTar); dTar->incrNodeDegree(RefDir::in, src); - if (src) { // Store the src -> tar reference assert(dSrc); @@ -222,15 +221,23 @@ void NodeManager::deleteRef(Node *tar, Node *src, bool all) // is larger than the threshold value and this function was not // called from inside the deleteNode function marked.insert(tar); - if (marked.size() >= threshold) { - sweep(); - } } } + + // Call the garbage collector if the marked size is larger than the actual + // value + if (marked.size() >= threshold) { + sweep(); + } } void NodeManager::deleteNode(Node *n, NodeDescriptor *descr) { + // Abort if the node already is on the "deleted" list + if (deleted.find(n) != deleted.end()) { + return; + } + // Increment the recursion depth counter. The "deleteRef" function called // below // may descend further into this function and the actual deletion should be @@ -277,6 +284,11 @@ void NodeManager::purgeDeleted() void NodeManager::sweep() { + // Only execute sweep on the highest recursion level + if (deletionRecursionDepth > 0) { + return; + } + // Set containing nodes which are reachable from a rooted node std::unordered_set reachable; diff --git a/src/core/dom/Node.hpp b/src/core/dom/Node.hpp index ce1e7f1..6869253 100644 --- a/src/core/dom/Node.hpp +++ b/src/core/dom/Node.hpp @@ -280,19 +280,19 @@ public: template Handle acquire(const BaseHandle &h) { - return Handle(h, this); + return Handle{h, this}; } template Handle acquire(BaseHandle &&h) { - return Handle(h, this); + return Handle{h, this}; } template Handle acquire(T *t) { - return Handle(t, this); + return Handle{t, this}; } }; @@ -317,6 +317,11 @@ public: */ BaseHandle(T *ptr) : ptr(ptr) {} + /** + * Returns the underlying pointer. + */ + T *get() const { return ptr; } + /** * Provides access to the underlying node. */ @@ -397,6 +402,25 @@ public: h.ptr = nullptr; } + /** + * Constructor of the handle class. + * + * @param ptr is the node the handle should represent. + */ + RootedHandle(T *ptr) : BaseHandle(ptr) { addRef(); } + + /** + * Constructor of the handle class. + * + * @param h is another handle whose Node should be used. + */ + template + RootedHandle(const BaseHandle &h) + : BaseHandle(h.get()) + { + addRef(); + } + /** * Assignment operator. Assigns the given handle to this handle instance. * Both handles are indistinguishable after the operation. @@ -453,20 +477,6 @@ public: return *this; } - /** - * Constructor of the handle class. - * - * @param ptr is the node the handle should represent. - */ - RootedHandle(T *ptr) : BaseHandle(ptr) { addRef(); } - - /** - * Constructor of the handle class. - * - * @param h is another handle whose Node should be used. - */ - RootedHandle(BaseHandle h) : BaseHandle(h.ptr) { addRef(); } - /** * Destructor of the RootedHandle class, deletes all refrences the class is * still holding. @@ -511,7 +521,20 @@ public: * * @param h is the handle that should be asigned to this instance. */ - Handle(const Handle &h) : BaseHandle(h.ptr), owner(h.owner) + Handle(const Handle &h) : BaseHandle(h.get()), owner(h.getOwner()) + { + addRef(); + } + + /** + * Copies the given handle of another derived type to this handle instance. + * Both handles are indistinguishable after the operation (except for the + * type). Note that especially the handle owner is copied. + * + * @param h is the handle that should be asigned to this instance. + */ + template + Handle(const Handle &h) : BaseHandle(h.get()), owner(h.getOwner()) { addRef(); } @@ -521,7 +544,7 @@ public: * * @param h is the handle to be moved to this instance. */ - Handle(Handle &&h) : BaseHandle(h.ptr), owner(h.owner) + Handle(Handle &&h) : BaseHandle(h.get()), owner(h.getOwner()) { h.ptr = nullptr; } @@ -537,7 +560,7 @@ public: { deleteRef(); this->ptr = h.ptr; - this->owner = h.owner; + this->owner = h.getOwner(); addRef(); return *this; } @@ -552,7 +575,7 @@ public: { deleteRef(); this->ptr = h.ptr; - this->owner = h.owner; + this->owner = h.getOwner(); h.ptr = nullptr; return *this; } @@ -573,34 +596,31 @@ public: * @param owner is the node which owns this handle instance. The ptr node * is guaranteed to live at least as long as the owner. */ - Handle(const BaseHandle &h, Node *owner) - : BaseHandle(h.ptr), owner(owner) + template + Handle(const BaseHandle &h, Node *owner) + : BaseHandle(h.get()), owner(owner) { addRef(); } - /** - * Constructor of the handle class. - * - * @param h is another handle whose Node should be used. - * @param owner is the node which owns this handle instance. The ptr node - * is guaranteed to live at least as long as the owner. - */ - Handle(BaseHandle &&h, Node *owner) : BaseHandle(h.ptr), owner(owner) - { - h.ptr = nullptr; - } - /** * Destructor of the Handle class, deletes all refrences the class is still * holding. */ ~Handle() { deleteRef(); } + + /** + * Returns the reference to the owner of the handle. + * + * @return the handle owner. + */ + Node* getOwner() const { + return owner; + } }; using RootedNode = RootedHandle; using NodeHandle = Handle; - } } -- cgit v1.2.3