Commit e0122c1e authored by Stephen Morris's avatar Stephen Morris

[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.
parent f1f8de8a
......@@ -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()) {
......
......@@ -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);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment