]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[2850] Fix MemorySegmentMapped::allMemoryDeallocated() and make it non-const
authorMukund Sivaraman <muks@isc.org>
Mon, 13 May 2013 08:36:58 +0000 (14:06 +0530)
committerMukund Sivaraman <muks@isc.org>
Mon, 13 May 2013 08:36:58 +0000 (14:06 +0530)
src/lib/util/memory_segment.h
src/lib/util/memory_segment_local.cc
src/lib/util/memory_segment_local.h
src/lib/util/memory_segment_mapped.cc
src/lib/util/memory_segment_mapped.h
src/lib/util/tests/memory_segment_mapped_unittest.cc

index a93b5ad0a3a995a53c6258279a65e0c5afb99beb..a613fd96ef48d6f29677fb1a7d51d2a49c3a654b 100644 (file)
@@ -157,7 +157,7 @@ public:
     /// \return Returns <code>true</code> if all allocated memory (including
     /// names associated by memory addresses by \c setNamedAddress()) was
     /// deallocated, <code>false</code> otherwise.
-    virtual bool allMemoryDeallocated() const = 0;
+    virtual bool allMemoryDeallocated() = 0;
 
     /// \brief Associate specified address in the segment with a given name.
     ///
index b81fe5e915f10004e8c4dab1e191618cb023a8b6..ec6ee664f848cf9f81d7779a10b2b5642dbb7db3 100644 (file)
@@ -47,7 +47,7 @@ MemorySegmentLocal::deallocate(void* ptr, size_t size) {
 }
 
 bool
-MemorySegmentLocal::allMemoryDeallocated() const {
+MemorySegmentLocal::allMemoryDeallocated() {
     return (allocated_size_ == 0 && named_addrs_.empty());
 }
 
index de7249e448709caeee6156f32085e37f0aa09fa2..d3e556ad45a3d0295d3bd7858f138daa6ace8425 100644 (file)
@@ -64,7 +64,7 @@ public:
     ///
     /// \return Returns <code>true</code> if all allocated memory was
     /// deallocated, <code>false</code> otherwise.
-    virtual bool allMemoryDeallocated() const;
+    virtual bool allMemoryDeallocated();
 
     /// \brief Local segment version of getNamedAddress.
     ///
index 2d0992d52b09c3358f9de1fc7dcf16715f288904..88bdaed2d830ab092be63ff9d188cf64b46c69bb 100644 (file)
@@ -139,11 +139,22 @@ struct MemorySegmentMapped::Impl {
 
     void reserveMemory() {
         if (!read_only_) {
-            // Reserve a named address for use during setNamedAddress().
-            const offset_ptr<void>* reserved_storage =
-                base_sgmt_->find_or_construct<offset_ptr<void> >(
-                    RESERVED_NAMED_ADDRESS_STORAGE_NAME, std::nothrow)();
-            assert(reserved_storage);
+            // Reserve a named address for use during
+            // setNamedAddress(). Though this will almost always succeed
+            // during construction, it may fail later during a call from
+            // allMemoryDeallocated() when the segment has been in use
+            // for a while.
+            while (true) {
+                const offset_ptr<void>* reserved_storage =
+                    base_sgmt_->find_or_construct<offset_ptr<void> >(
+                        RESERVED_NAMED_ADDRESS_STORAGE_NAME, std::nothrow)();
+
+                if (reserved_storage) {
+                    break;
+                }
+
+                growSegment();
+            }
         }
     }
 
@@ -306,8 +317,12 @@ MemorySegmentMapped::deallocate(void* ptr, size_t) {
 }
 
 bool
-MemorySegmentMapped::allMemoryDeallocated() const {
-    return (impl_->base_sgmt_->all_memory_deallocated());
+MemorySegmentMapped::allMemoryDeallocated() {
+    impl_->freeReservedMemory();
+    const bool result = impl_->base_sgmt_->all_memory_deallocated();
+    impl_->reserveMemory();
+
+    return (result);
 }
 
 MemorySegment::NamedAddressResult
index 492cf866f111b7532457a39e527ba75a2b18e954..7702d8852e81b23384af0415873906bbe301e11f 100644 (file)
@@ -175,7 +175,7 @@ public:
     /// read-only mode; in that case MemorySegmentError will be thrown.
     virtual void deallocate(void* ptr, size_t size);
 
-    virtual bool allMemoryDeallocated() const;
+    virtual bool allMemoryDeallocated();
 
     /// \brief Mapped segment version of setNamedAddress.
     ///
index f8eeb5b5f0db823f0b963ba798ae90deff6f7ba4..dc8dffc95a2a1d2dc344e3937f984fc77595a2a9 100644 (file)
@@ -467,7 +467,14 @@ TEST_F(MemorySegmentMappedTest, shrink) {
     EXPECT_EQ(shrinked_size, segment_->getSize());
 
     // Check that the segment is still usable after shrink.
-    void* p = segment_->allocate(sizeof(uint32_t));
+    void *p = NULL;
+    while (!p) {
+        try {
+            p = segment_->allocate(sizeof(uint32_t));
+        } catch (const MemorySegmentGrown&) {
+            // Do nothing. Just try again.
+        }
+    }
     segment_->deallocate(p, sizeof(uint32_t));
 }