Browse Source

[2836] Retry addition on segment grow

If the segment grows during the addition of some data, update the
pointer for the zone data and retry the addition. Repeat until it
succeeds (it is possible, at least in theory, there'll be more segment
growths during single addition, one for the tree structure and one for
the actual data).
Michal 'vorner' Vaner 12 years ago
parent
commit
42a5a79525
1 changed files with 26 additions and 1 deletions
  1. 26 1
      src/lib/datasrc/memory/zone_data_updater.cc

+ 26 - 1
src/lib/datasrc/memory/zone_data_updater.cc

@@ -415,7 +415,32 @@ ZoneDataUpdater::add(const ConstRRsetPtr& rrset,
         arg(rrset ? rrtype.toText() : "RRSIG(" + rrtype.toText() + ")").
         arg(rrset ? rrtype.toText() : "RRSIG(" + rrtype.toText() + ")").
         arg(zone_name_);
         arg(zone_name_);
 
 
-    addInternal(name, rrtype, rrset, sig_rrset);
+    // Store the address, it may change during growth and the address inside
+    // would get updated.
+    mem_sgmt_.setNamedAddress("updater_zone_data", zone_data_);
+    bool added = false;
+    do {
+        try {
+            addInternal(name, rrtype, rrset, sig_rrset);
+            added = true;
+        } catch (const isc::util::MemorySegmentGrown&) {
+            // The segment has grown. So, we update the base pointer (because
+            // the data may have been remapped somewhere else in the process).
+            zone_data_ =
+                static_cast<ZoneData*>(
+                    mem_sgmt_.getNamedAddress("updater_zone_data"));
+        } catch (...) {
+            // In case of other exceptions, they are propagated. But clean up
+            // the temporary address stored there (this is shorter than
+            // RAII class in this case).
+            mem_sgmt_.clearNamedAddress("updater_zone_data");
+            throw;
+        }
+        // Retry if it didn't add due to the growth
+    } while (!added);
+
+    // Clean up the named address
+    mem_sgmt_.clearNamedAddress("updater_zone_data");
 }
 }
 
 
 } // namespace memory
 } // namespace memory