]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Segment.cc
4 * DEBUG: section 54 Interprocess Communication
9 #include "base/TextException.h"
10 #include "compat/shm.h"
11 #include "ipc/mem/Segment.h"
17 #include <sys/types.h>
20 Ipc::Mem::Segment::Segment(const char *const id
):
21 theName(GenerateName(id
)), theFD(-1), theMem(NULL
),
22 theSize(0), theReserved(0), doUnlink(false)
26 Ipc::Mem::Segment::~Segment()
30 if (close(theFD
) != 0)
31 debugs(54, 5, HERE
<< "close " << theName
<< ": " << xstrerror());
38 Ipc::Mem::Segment::Enabled()
48 Ipc::Mem::Segment::create(const off_t aSize
)
53 theFD
= shm_open(theName
.termedBuf(), O_CREAT
| O_RDWR
| O_TRUNC
,
56 debugs(54, 5, HERE
<< "shm_open " << theName
<< ": " << xstrerror());
57 fatal("Ipc::Mem::Segment::create failed to shm_open");
60 if (ftruncate(theFD
, aSize
)) {
61 debugs(54, 5, HERE
<< "ftruncate " << theName
<< ": " << xstrerror());
62 fatal("Ipc::Mem::Segment::create failed to ftruncate");
65 assert(statSize("Ipc::Mem::Segment::create") == aSize
); // paranoid
71 debugs(54, 3, HERE
<< "created " << theName
<< " segment: " << theSize
);
77 Ipc::Mem::Segment::open()
81 theFD
= shm_open(theName
.termedBuf(), O_RDWR
, 0);
83 debugs(54, 5, HERE
<< "shm_open " << theName
<< ": " << xstrerror());
84 String s
= "Ipc::Mem::Segment::open failed to shm_open ";
89 theSize
= statSize("Ipc::Mem::Segment::open");
91 debugs(54, 3, HERE
<< "opened " << theName
<< " segment: " << theSize
);
96 /// Map the shared memory segment to the process memory space.
98 Ipc::Mem::Segment::attach()
103 // mmap() accepts size_t for the size; we give it off_t which might
104 // be bigger; assert overflows until we support multiple mmap()s?
105 assert(theSize
== static_cast<off_t
>(static_cast<size_t>(theSize
)));
108 mmap(NULL
, theSize
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, theFD
, 0);
109 if (p
== MAP_FAILED
) {
110 debugs(54, 5, HERE
<< "mmap " << theName
<< ": " << xstrerror());
111 fatal("Ipc::Mem::Segment::attach failed to mmap");
116 /// Unmap the shared memory segment from the process memory space.
118 Ipc::Mem::Segment::detach()
123 if (munmap(theMem
, theSize
)) {
124 debugs(54, 5, HERE
<< "munmap " << theName
<< ": " << xstrerror());
125 fatal("Ipc::Mem::Segment::detach failed to munmap");
131 Ipc::Mem::Segment::unlink()
133 if (shm_unlink(theName
.termedBuf()) != 0)
134 debugs(54, 5, HERE
<< "shm_unlink(" << theName
<< "): " << xstrerror());
136 debugs(54, 3, HERE
<< "unlinked " << theName
<< " segment");
140 Ipc::Mem::Segment::reserve(size_t chunkSize
)
143 // check for overflows
144 // chunkSize >= 0 may result in warnings on systems where off_t is unsigned
145 assert(!chunkSize
|| static_cast<off_t
>(chunkSize
) > 0);
146 assert(static_cast<off_t
>(chunkSize
) <= theSize
);
147 assert(theReserved
<= theSize
- static_cast<off_t
>(chunkSize
));
148 void *result
= reinterpret_cast<char*>(theMem
) + theReserved
;
149 theReserved
+= chunkSize
;
153 /// determines the size of the underlying "file"
155 Ipc::Mem::Segment::statSize(const char *context
) const
160 memset(&s
, 0, sizeof(s
));
162 if (fstat(theFD
, &s
) != 0) {
163 debugs(54, 5, HERE
<< "fstat " << theName
<< ": " << xstrerror());
165 s
.append("failed to fstat(2) ");
167 fatal(s
.termedBuf());
173 /// Generate name for shared memory segment. Replaces all slashes with dots.
175 Ipc::Mem::Segment::GenerateName(const char *id
)
177 String
name("/squid-");
178 for (const char *slash
= strchr(id
, '/'); slash
; slash
= strchr(id
, '/')) {
180 name
.append(id
, slash
- id
);