Browse Source

[1747] added RAII-lookalike cleaner object to Query::process()

Jelte Jansen 13 years ago
parent
commit
5c681eddd0
2 changed files with 32 additions and 14 deletions
  1. 14 7
      src/bin/auth/query.cc
  2. 18 7
      src/bin/auth/query.h

+ 14 - 7
src/bin/auth/query.cc

@@ -90,6 +90,7 @@ getAdditional(const Name& qname, RRType qtype,
         results.push_back(*it);
     }
 }
+
 }
 
 namespace isc {
@@ -355,11 +356,9 @@ Query::process(datasrc::DataSourceClient& datasrc_client,
                const isc::dns::Name& qname, const isc::dns::RRType& qtype,
                isc::dns::Message& response, bool dnssec)
 {
-    // First a bit of house cleaning
-    // The call to reset() could in theory be ommitted, but
-    // seems prudent, just in case a previous process() left
-    // data in here.
-    reset();
+    // Set up the cleaner object so internal pointers and vectors are
+    // always reset after scope leaves this method
+    QueryCleaner cleaner(*this);
 
     // Set up query parameters for the rest of the (internal) methods
     initialize(datasrc_client, qname, qtype, response, dnssec);
@@ -556,12 +555,20 @@ void
 Query::createResponse() {
     for_each(answers_.begin(), answers_.end(),
              RRsetInserter(*response_, Message::SECTION_ANSWER, dnssec_));
-    answers_.clear();
     for_each(authorities_.begin(), authorities_.end(),
              RRsetInserter(*response_, Message::SECTION_AUTHORITY, dnssec_));
-    authorities_.clear();
     for_each(additionals_.begin(), additionals_.end(),
              RRsetInserter(*response_, Message::SECTION_ADDITIONAL, dnssec_));
+}
+
+void
+Query::reset() {
+    datasrc_client_ = NULL;
+    qname_ = NULL;
+    qtype_ = NULL;
+    response_ = NULL;
+    answers_.clear();
+    authorities_.clear();
     additionals_.clear();
 }
 

+ 18 - 7
src/bin/auth/query.h

@@ -264,13 +264,23 @@ private:
     /// After they are added, the vectors are cleared.
     void createResponse();
 
-    /// \brief Resets any partly built response data
-    void
-    reset() {
-        answers_.clear();
-        authorities_.clear();
-        additionals_.clear();
-    }
+    /// \brief Resets any partly built response data, and internal pointers
+    ///
+    /// Called by the QueryCleaner object upon its destruction
+    void reset();
+
+    /// \brief Internal class used for cleanup of Query members
+    ///
+    /// The process() call creates an object of this class, which
+    /// upon its destruction, calls Query::reset(), so that outside
+    /// of single calls to process(), the query state is always clean.
+    class QueryCleaner {
+    public:
+        QueryCleaner(isc::auth::Query& query) : query_(query) {}
+        ~QueryCleaner() { query_.reset(); }
+    private:
+        isc::auth::Query& query_;
+    };
 
 public:
     /// Default constructor.
@@ -287,6 +297,7 @@ public:
         additionals_.reserve(RESERVE_RRSETS);
     }
 
+
     /// Process the query.
     ///
     /// This method first identifies the zone that best matches the query