"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 | 110 +++++++++++++++++++++++++++++++++++++++-------- src/ipc/mem/Segment.h | 18 ++++++-- 2 files changed, 105 insertions(+), 23 deletions(-) diff --git src/ipc/mem/Segment.cc src/ipc/mem/Segment.cc index 98c393c..5702fd0 100644 --- src/ipc/mem/Segment.cc +++ src/ipc/mem/Segment.cc @@ -16,8 +16,24 @@ #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 diff --git src/ipc/mem/Segment.h src/ipc/mem/Segment.h index 138de2b..b82ac4f 100644 --- src/ipc/mem/Segment.h +++ src/ipc/mem/Segment.h @@ -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 -- 1.7.6.3Received on Wed Sep 28 2011 - 23:06:49 MDT
This archive was generated by hypermail 2.2.0 : Thu Sep 29 2011 - 12:00:03 MDT