Browse Source

[trac641] Added destructor to TestResolver to cure memory leaks

Reverted ZoneEntry to the original version and added the destructor
to TestResolver to call all the saved callbacks.  This breaks
internal shared_ptr loops, allowing the NSAS to destoy itself
gracefully, and avoiding memory leaks.
Stephen Morris 14 years ago
parent
commit
e0122c1e32
2 changed files with 21 additions and 11 deletions
  1. 12 0
      src/lib/nsas/tests/nsas_test.h
  2. 9 11
      src/lib/nsas/zone_entry.cc

+ 12 - 0
src/lib/nsas/tests/nsas_test.h

@@ -240,6 +240,18 @@ class TestResolver : public isc::resolve::ResolverInterface {
     public:
         typedef pair<QuestionPtr, CallbackPtr> Request;
         vector<Request> requests;
+
+        /// \brief Destructor
+        ///
+        /// This is important.  All callbacks in the requests vector must be
+        /// called to remove them from internal loops.  Without this, destroying
+        /// the NSAS object will leave memory assigned.
+        ~TestResolver() {
+            for (size_t i = 0; i < requests.size(); ++i) {
+                requests[i].second->failure();
+            }
+        }
+
         virtual void resolve(const QuestionPtr& q, const CallbackPtr& c) {
             PresetAnswers::iterator it(answers_.find(*q));
             if (it == answers_.end()) {

+ 9 - 11
src/lib/nsas/zone_entry.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <map>
+
 #include <config.h>
 
 #include "zone_entry.h"
@@ -80,7 +81,7 @@ class ZoneEntry::ResolverCallback :
         public isc::resolve::ResolverInterface::Callback {
     public:
         /// \short Constructor. Pass "this" zone entry
-        ResolverCallback(ZoneEntry* entry) :
+        ResolverCallback(boost::shared_ptr<ZoneEntry> entry) :
             entry_(entry)
         { }
         /**
@@ -218,9 +219,8 @@ class ZoneEntry::ResolverCallback :
             // Process all three callback lists and tell them KO
             entry_->process(ADDR_REQ_MAX, NameserverPtr());
         }
-        // The entry we are callback of.  As this object will hold a
-        // shared pointer to us, a "raw" pointer is fine here.
-        ZoneEntry* entry_;
+        /// \short The entry we are callback of
+        boost::shared_ptr<ZoneEntry> entry_;
 };
 
 void
@@ -255,7 +255,7 @@ ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
         QuestionPtr question(new Question(Name(name_), class_code_,
             RRType::NS()));
         boost::shared_ptr<ResolverCallback> resolver_callback(
-            new ResolverCallback(this));
+            new ResolverCallback(shared_from_this()));
         resolver_->resolve(question, resolver_callback);
         return;
     }
@@ -264,7 +264,7 @@ ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
 void
 ZoneEntry::removeCallback(const CallbackPtr& callback, AddressFamily family) {
     Lock lock(mutex_);
-    std::vector<boost::shared_ptr<AddressRequestCallback> >::iterator i =
+    std::vector<boost::shared_ptr<AddressRequestCallback> >::iterator i = 
         callbacks_[family].begin();
     for (; i != callbacks_[family].end(); ++i) {
         if (*i == callback) {
@@ -371,7 +371,7 @@ class ZoneEntry::NameserverCallback : public NameserverEntry::Callback {
          * \param family For which address family this change is, so we
          *     do not process all the nameserves and callbacks there.
          */
-        NameserverCallback(ZoneEntry* entry, AddressFamily family) :
+        NameserverCallback(boost::shared_ptr<ZoneEntry> entry, AddressFamily family) :
             entry_(entry),
             family_(family)
         { }
@@ -386,9 +386,7 @@ class ZoneEntry::NameserverCallback : public NameserverEntry::Callback {
             entry_->process(family_, ns);
         }
     private:
-        // The entry we are callback of.  As this object will hold a
-        // shared pointer to us, a "raw" pointer is fine here.
-        ZoneEntry* entry_;
+        boost::shared_ptr<ZoneEntry> entry_;
         AddressFamily family_;
 };
 
@@ -553,7 +551,7 @@ ZoneEntry::insertCallback(NameserverPtr ns, AddressFamily family) {
         insertCallback(ns, V6_ONLY);
     } else {
         boost::shared_ptr<NameserverCallback> callback(new NameserverCallback(
-            this, family));
+            shared_from_this(), family));
         ns->askIP(resolver_, callback, family);
     }
 }