]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[2831] use null mutex for managed mapped file.
authorJINMEI Tatuya <jinmei@isc.org>
Wed, 13 Mar 2013 07:25:43 +0000 (00:25 -0700)
committerJINMEI Tatuya <jinmei@isc.org>
Wed, 13 Mar 2013 07:25:43 +0000 (00:25 -0700)
it eliminates possible dependency on pthread library (which is not needed
for the memory segment class) and possible build time troubles due to that.

src/lib/util/memory_segment_mapped.cc

index 9aed111b61e7d8ecfad74cdd528e0843fd3ad395..c3ae7171eddc44636fe7905586e877c44d0bb280 100644 (file)
 #include <string>
 #include <new>
 
-using boost::interprocess::managed_mapped_file;
-using boost::interprocess::open_or_create;
-using boost::interprocess::open_only;
-using boost::interprocess::open_read_only;
-using boost::interprocess::offset_ptr;
+using namespace boost::interprocess;
 
 namespace isc {
 namespace util {
 
+// We customize managed_mapped_file to make it completely lock free.  In our
+// usage the application (or the system of applications) is expected to ensure
+// there's at most one writer process or concurrent writing the shared memory
+// segment is protected at a higher level.  Using the null mutex is mainly for
+// eliminating unnecessary dependency; the default version would require
+// (probably depending on the system) Pthread library that is actually not
+// needed and could cause various build time troubles.
+typedef basic_managed_mapped_file<char,
+                                  rbtree_best_fit<null_mutex_family>,
+                                  iset_index> BaseSegment;
+
 struct MemorySegmentMapped::Impl {
     Impl(const std::string& filename, size_t initial_size) :
         read_only_(false), filename_(filename),
-        base_sgmt_(new managed_mapped_file(open_or_create, filename.c_str(),
-                                           initial_size))
+        base_sgmt_(new BaseSegment(open_or_create, filename.c_str(),
+                                   initial_size))
     {}
 
     Impl(const std::string& filename, bool read_only) :
         read_only_(read_only), filename_(filename),
         base_sgmt_(read_only ?
-                   new managed_mapped_file(open_read_only, filename.c_str()) :
-                   new managed_mapped_file(open_only, filename.c_str()))
+                   new BaseSegment(open_read_only, filename.c_str()) :
+                   new BaseSegment(open_only, filename.c_str()))
     {}
 
     // Internal helper to grow the underlying mapped segment.
@@ -57,8 +64,7 @@ struct MemorySegmentMapped::Impl {
         const size_t new_size = prev_size * 2;
         assert(new_size != 0); // assume grow fails before size overflow
 
-        if (!managed_mapped_file::grow(filename_.c_str(),
-                                       new_size - prev_size))
+        if (!BaseSegment::grow(filename_.c_str(), new_size - prev_size))
         {
             throw std::bad_alloc();
         }
@@ -67,8 +73,7 @@ struct MemorySegmentMapped::Impl {
             // Remap the grown file; this should succeed, but it's not 100%
             // guaranteed.  If it fails we treat it as if we fail to create
             // the new segment.
-            base_sgmt_.reset(new managed_mapped_file(open_only,
-                                                     filename_.c_str()));
+            base_sgmt_.reset(new BaseSegment(open_only, filename_.c_str()));
         } catch (const boost::interprocess::interprocess_exception& ex) {
             throw std::bad_alloc();
         }
@@ -81,7 +86,7 @@ struct MemorySegmentMapped::Impl {
     const std::string filename_;
 
     // actual Boost implementation of mapped segment.
-    boost::scoped_ptr<managed_mapped_file> base_sgmt_;
+    boost::scoped_ptr<BaseSegment> base_sgmt_;
 };
 
 MemorySegmentMapped::MemorySegmentMapped(const std::string& filename) :
@@ -224,13 +229,13 @@ MemorySegmentMapped::shrinkToFit() {
     }
 
     impl_->base_sgmt_.reset();
-    managed_mapped_file::shrink_to_fit(impl_->filename_.c_str());
+    BaseSegment::shrink_to_fit(impl_->filename_.c_str());
     try {
         // Remap the grown file; this should succeed, but it's not 100%
         // guaranteed.  If it fails we treat it as if we fail to create
         // the new segment.
         impl_->base_sgmt_.reset(
-            new managed_mapped_file(open_only, impl_->filename_.c_str()));
+            new BaseSegment(open_only, impl_->filename_.c_str()));
     } catch (const boost::interprocess::interprocess_exception& ex) {
         isc_throw(MemorySegmentError,
                   "remap after shrink failed; segment is now unusable");