*/
#include "config.h"
-
+#include "base/TextException.h"
#include "ipc/mem/Segment.h"
#include "protos.h"
}
void
-Ipc::Mem::Segment::create(const int aSize)
+Ipc::Mem::Segment::create(const off_t aSize)
{
assert(aSize > 0);
assert(theFD < 0);
fatal("Ipc::Mem::Segment::create failed to ftruncate");
}
+ assert(statSize("Ipc::Mem::Segment::create") == aSize); // paranoid
+
theSize = aSize;
theReserved = 0;
fatal(s.termedBuf());
}
- {
- struct stat s;
- memset(&s, 0, sizeof(s));
- if (fstat(theFD, &s)) {
- debugs(54, 5, HERE << "fstat: " << xstrerror());
- String s = "Ipc::Mem::Segment::open failed to fstat";
- s.append(theName);
- fatal(s.termedBuf());
- }
-
- theSize = s.st_size;
- }
+ theSize = statSize("Ipc::Mem::Segment::open");
debugs(54, 3, HERE << "opened " << theName << " segment: " << theSize);
void *
Ipc::Mem::Segment::reserve(size_t chunkSize)
{
- assert(chunkSize <= theSize);
- assert(theReserved <= theSize - chunkSize);
+ // check for overflows
+ assert(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*>(mem()) + theReserved;
theReserved += chunkSize;
return result;
}
+/// determines the size of the underlying "file"
+off_t
+Ipc::Mem::Segment::statSize(const char *context) const
+{
+ Must(theFD >= 0);
+
+ struct stat s;
+ memset(&s, 0, sizeof(s));
+
+ if (fstat(theFD, &s) != 0) {
+ debugs(54, 5, HERE << "fstat: " << xstrerror());
+ String s = context;
+ s.append("failed to fstat(2)");
+ s.append(theName);
+ fatal(s.termedBuf());
+ }
+
+ return s.st_size;
+}
+
/// Generate name for shared memory segment. Replaces all slashes with dots.
String
Ipc::Mem::Segment::GenerateName(const char *id)
/// Create a new shared memory segment. Fails if a segment with
/// the same name already exists.
- void create(const int aSize);
+ void create(const off_t aSize);
void open(); ///< Open an existing shared memory segment.
const String &name() { return theName; } ///< shared memory segment name
- int size() { return theSize; } ///< shared memory segment size
+ off_t size() { return theSize; } ///< shared memory segment size
void *mem() { return theMem; } ///< pointer to mmapped shared memory segment
void *reserve(size_t chunkSize); ///< reserve and return the next chunk
// TODO: convert most mem() calls to reserve()
private:
void attach();
void detach();
+ off_t statSize(const char *context) const;
static String GenerateName(const char *id);
const String theName; ///< shared memory segment file name
int theFD; ///< shared memory segment file descriptor
void *theMem; ///< pointer to mmapped shared memory segment
- size_t theSize; ///< shared memory segment size
- size_t theReserved; ///< the total number of reserve()d bytes
+ off_t theSize; ///< shared memory segment size
+ off_t theReserved; ///< the total number of reserve()d bytes
};
} // namespace Mem