Browse Source

[2831] use null mutex for managed mapped file.

it eliminates possible dependency on pthread library (which is not needed
for the memory segment class) and possible build time troubles due to that.
JINMEI Tatuya 12 years ago
parent
commit
8e75dec19b
1 changed files with 21 additions and 16 deletions
  1. 21 16
      src/lib/util/memory_segment_mapped.cc

+ 21 - 16
src/lib/util/memory_segment_mapped.cc

@@ -24,27 +24,34 @@
 #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");