Browse Source

Don't forget to report failures

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac408@3715 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
85dc9a0f23
3 changed files with 35 additions and 16 deletions
  1. 1 1
      src/lib/nsas/tests/zone_entry_unittest.cc
  2. 28 14
      src/lib/nsas/zone_entry.cc
  3. 6 1
      src/lib/nsas/zone_entry.h

+ 1 - 1
src/lib/nsas/tests/zone_entry_unittest.cc

@@ -197,9 +197,9 @@ TEST_F(ZoneEntryTest, CallbacksAOnly) {
     EXPECT_EQ(0, callback_->successes_.size());
     EXPECT_EQ(1, callback_->unreachable_count_);
     // Answer the A one and see it answers what can be answered
-    ASSERT_EQ(2, callback_->successes_.size());
     EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
         rdata::in::A("192.0.2.1")));
+    ASSERT_EQ(2, callback_->successes_.size());
     EXPECT_TRUE(IOAddress("192.0.2.1").equal(callback_->successes_[0]));
     EXPECT_TRUE(IOAddress("192.0.2.1").equal(callback_->successes_[1]));
     EXPECT_EQ(1, callback_->unreachable_count_);

+ 28 - 14
src/lib/nsas/zone_entry.cc

@@ -251,6 +251,24 @@ class ZoneEntry::NameserverCallback : public NameserverEntry::Callback {
 };
 
 void
+ZoneEntry::dispatchFailures(AddressFamily family, shared_ptr<Lock> lock) {
+    // We extract all the callbacks
+    vector<CallbackPtr> callbacks;
+    if (family == ADDR_REQ_MAX) {
+        move(callbacks_[ANY_OK], callbacks_[V4_ONLY]);
+        move(callbacks_[ANY_OK], callbacks_[V6_ONLY]);
+        family = ANY_OK;
+    }
+    callbacks.swap(callbacks_[family]);
+    // We want to call them not locked, so we both do not block the
+    // lock and allow them to call our functions
+    lock->unlock();
+    BOOST_FOREACH(const CallbackPtr& callback, callbacks) {
+        callback->unreachable();
+    }
+}
+
+void
 ZoneEntry::process(CallbackPtr callback, AddressFamily family,
     shared_ptr<NameserverEntry> nameserver, shared_ptr<ZoneEntry> self,
     shared_ptr<Lock> lock)
@@ -272,20 +290,7 @@ ZoneEntry::process(CallbackPtr callback, AddressFamily family,
         case EXPIRED:
             return;
         case UNREACHABLE: {
-            // We extract all the callbacks
-            vector<CallbackPtr> callbacks;
-            if (family == ADDR_REQ_MAX) {
-                move(callbacks_[ANY_OK], callbacks_[V4_ONLY]);
-                move(callbacks_[ANY_OK], callbacks_[V6_ONLY]);
-                family = ANY_OK;
-            }
-            callbacks.swap(callbacks_[family]);
-            // We want to call them not locked, so we both do not block the
-            // lock and allow them to call our functions
-            lock->unlock();
-            BOOST_FOREACH(const CallbackPtr& callback, callbacks) {
-                callback->unreachable();
-            }
+            dispatchFailures(family, lock);
             // And we do nothing more now
             return;
         }
@@ -381,12 +386,21 @@ ZoneEntry::process(CallbackPtr callback, AddressFamily family,
                 } else if (!addresses.empty()) {
                     // Extract the callbacks
                     vector<CallbackPtr> to_execute;
+                    // FIXME: Think of a solution where we do not lose
+                    // any callbacks upon exception
                     to_execute.swap(callbacks_[family]);
 
                     // Unlock, the callbacks might want to call us
+                    lock->unlock();
+
+                    // Run the callbacks
                     BOOST_FOREACH(const CallbackPtr& callback, to_execute) {
                         callback->success(chooseAddress(addresses));
                     }
+                    return;
+                } else if (!pending) {
+                    dispatchFailures(family, lock);
+                    return;
                 }
             }
             return;

+ 6 - 1
src/lib/nsas/zone_entry.h

@@ -125,7 +125,7 @@ private:
     // If the familly is ADDR_REQ_MAX, then it means process all callbacks.
     // However, you must not provide callback.
     // If lock is provided, it is locked mutex_ and will be used. If not,
-    // will use its own.
+    // will use its own. It might unlock the lock.
     void process(boost::shared_ptr<AddressRequestCallback> callback,
          AddressFamily family, boost::shared_ptr<NameserverEntry> nameserver,
          boost::shared_ptr<ZoneEntry> self,
@@ -149,6 +149,11 @@ private:
     // Callback from nameserver entry
     class NameserverCallback;
     // And it can get into our internals as well (call process)
+    friend class NameserverCallback;
+    // This dispatches callbacks of given family with failures (and unlocks)
+    // The lock is mandatory
+    void dispatchFailures(AddressFamily family,
+        boost::shared_ptr<boost::mutex::scoped_lock> lock);
 };
 
 } // namespace nsas