]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Add "fake" shared memory segment implementation.
authorDmitry Kurochkin <dmitry.kurochkin@measurement-factory.com>
Tue, 4 Oct 2011 17:25:56 +0000 (21:25 +0400)
committerDmitry Kurochkin <dmitry.kurochkin@measurement-factory.com>
Tue, 4 Oct 2011 17:25:56 +0000 (21:25 +0400)
"Fake" shared memory segments are enabled #if a system does not
support POSIX shared memory.  Such segments use regular new to
allocate memory, it is not shared among multiple processes.  The
purpose of the change is to allow code that uses Ipc::Mem::Segment to
run in non-SMP mode (that is when only a single process, except for
master, is running) on systems without POSIX shared memory support.

Note: running SHM-using features in SMP mode still requires POSIX
shared memory support, the patch does not change that.

src/ipc/mem/Segment.cc
src/ipc/mem/Segment.h

index 98c393ce3cb64a569b96181149bd9d3dd38cee36..5702fd0f6a9f5ecd72adbcc0f9c1d77e3112f1a3 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 
+void *
+Ipc::Mem::Segment::reserve(size_t chunkSize)
+{
+    Must(theMem);
+    // check for overflows
+    // chunkSize >= 0 may result in warnings on systems where off_t is unsigned
+    assert(!chunkSize || static_cast<off_t>(chunkSize) > 0);
+    assert(static_cast<off_t>(chunkSize) <= theSize);
+    assert(theReserved <= theSize - static_cast<off_t>(chunkSize));
+    void *result = reinterpret_cast<char*>(theMem) + theReserved;
+    theReserved += chunkSize;
+    return result;
+}
+
+#if HAVE_SHM
+
 Ipc::Mem::Segment::Segment(const char *const id):
-        theName(GenerateName(id)), theFD(-1), theMem(NULL),
+        theFD(-1), theName(GenerateName(id)), theMem(NULL),
         theSize(0), theReserved(0), doUnlink(false)
 {
 }
@@ -33,14 +49,11 @@ Ipc::Mem::Segment::~Segment()
         unlink();
 }
 
+// fake Ipc::Mem::Segment::Enabled (!HAVE_SHM) is more selective
 bool
 Ipc::Mem::Segment::Enabled()
 {
-#if HAVE_SHM
     return true;
-#else
-    return false;
-#endif
 }
 
 void
@@ -135,20 +148,6 @@ Ipc::Mem::Segment::unlink()
         debugs(54, 3, HERE << "unlinked " << theName << " segment");
 }
 
-void *
-Ipc::Mem::Segment::reserve(size_t chunkSize)
-{
-    Must(theMem);
-    // check for overflows
-    // chunkSize >= 0 may result in warnings on systems where off_t is unsigned
-    assert(!chunkSize || static_cast<off_t>(chunkSize) > 0);
-    assert(static_cast<off_t>(chunkSize) <= theSize);
-    assert(theReserved <= theSize - static_cast<off_t>(chunkSize));
-    void *result = reinterpret_cast<char*>(theMem) + theReserved;
-    theReserved += chunkSize;
-    return result;
-}
-
 /// determines the size of the underlying "file"
 off_t
 Ipc::Mem::Segment::statSize(const char *context) const
@@ -184,3 +183,76 @@ Ipc::Mem::Segment::GenerateName(const char *id)
     name.append(id);
     return name;
 }
+
+#else // HAVE_SHM
+
+#include <map>
+
+typedef std::map<String, Ipc::Mem::Segment *> SegmentMap;
+static SegmentMap Segments;
+
+Ipc::Mem::Segment::Segment(const char *const id):
+    theName(id), theMem(NULL), theSize(0), theReserved(0), doUnlink(false)
+{
+}
+
+Ipc::Mem::Segment::~Segment()
+{
+    if (doUnlink) {
+        delete [] static_cast<char *>(theMem);
+        debugs(54, 3, HERE << "deleted " << theName << " segment");
+    }
+}
+
+bool
+Ipc::Mem::Segment::Enabled()
+{
+    return !InDaemonMode() || (!UsingSmp() && IamWorkerProcess());
+}
+
+void
+Ipc::Mem::Segment::create(const off_t aSize)
+{
+    assert(aSize > 0);
+    assert(!theMem);
+    checkSupport("Fake segment creation");
+
+    const bool inserted = Segments.insert(std::make_pair(theName, this)).second;
+    if (!inserted)
+        fatalf("Duplicate fake segment creation: %s", theName.termedBuf());
+
+    theMem = new char[aSize];
+    theSize = aSize;
+    doUnlink = true;
+
+    debugs(54, 3, HERE << "created " << theName << " fake segment: " << theSize);
+}
+
+void
+Ipc::Mem::Segment::open()
+{
+    assert(!theMem);
+    checkSupport("Fake segment open");
+
+    const SegmentMap::const_iterator i = Segments.find(theName);
+    if (i == Segments.end())
+        fatalf("Fake segment not found: %s", theName.termedBuf());
+
+    const Segment &segment = *i->second;
+    theMem = segment.theMem;
+    theSize = segment.theSize;
+
+    debugs(54, 3, HERE << "opened " << theName << " fake segment: " << theSize);
+}
+
+void
+Ipc::Mem::Segment::checkSupport(const char *const context)
+{
+    if (!Enabled()) {
+        debugs(54, 5, HERE << "True shared memory segments are not supported. "
+               "Cannot fake shared segments in SMP config.");
+        fatalf("%s failed", context);
+    }
+}
+
+#endif // HAVE_SHM
index 138de2b98cc348426bc256e3cb1597a158636b12..b82ac4fab730773365ad03621e767bdab65838bb 100644 (file)
@@ -36,6 +36,13 @@ public:
 
 
 private:
+
+    // not implemented
+    Segment(const Segment &);
+    Segment &operator =(const Segment &);
+
+#if HAVE_SHM
+
     void attach();
     void detach();
     void unlink(); ///< unlink the segment
@@ -43,12 +50,15 @@ private:
 
     static String GenerateName(const char *id);
 
-    // not implemented
-    Segment(const Segment &);
-    Segment &operator =(const Segment &);
+    int theFD; ///< shared memory segment file descriptor
+
+#else // HAVE_SHM
+
+    void checkSupport(const char *const context);
+
+#endif // HAVE_SHM
 
     const String theName; ///< shared memory segment file name
-    int theFD; ///< shared memory segment file descriptor
     void *theMem; ///< pointer to mmapped shared memory segment
     off_t theSize; ///< shared memory segment size
     off_t theReserved; ///< the total number of reserve()d bytes