]>
Commit | Line | Data |
---|---|---|
f5eef98c DK |
1 | /* |
2 | * $Id$ | |
3 | * | |
4 | * DEBUG: section 54 Interprocess Communication | |
5 | * | |
6 | */ | |
7 | ||
8 | #include "config.h" | |
9 | ||
d8a82533 | 10 | #include "ipc/mem/Segment.h" |
f5eef98c DK |
11 | #include "protos.h" |
12 | ||
13 | #include <fcntl.h> | |
14 | #include <sys/mman.h> | |
15 | #include <sys/stat.h> | |
16 | #include <sys/types.h> | |
17 | #include <unistd.h> | |
18 | ||
d8a82533 | 19 | Ipc::Mem::Segment::Segment(const char *const id): |
937d0d3f AR |
20 | theName(GenerateName(id)), theFD(-1), theMem(NULL), |
21 | theSize(0), theReserved(0) | |
f5eef98c DK |
22 | { |
23 | } | |
24 | ||
d8a82533 | 25 | Ipc::Mem::Segment::~Segment() { |
f5eef98c DK |
26 | if (theFD >= 0) { |
27 | detach(); | |
d8a82533 AR |
28 | if (close(theFD) != 0) |
29 | debugs(54, 5, HERE << "close: " << xstrerror()); | |
f5eef98c DK |
30 | } |
31 | } | |
32 | ||
33 | void | |
d8a82533 | 34 | Ipc::Mem::Segment::create(const int aSize) |
f5eef98c DK |
35 | { |
36 | assert(aSize > 0); | |
37 | assert(theFD < 0); | |
38 | ||
e1825c5d | 39 | theFD = shm_open(theName.termedBuf(), O_CREAT | O_RDWR | O_TRUNC, |
f5eef98c DK |
40 | S_IRUSR | S_IWUSR); |
41 | if (theFD < 0) { | |
d8a82533 AR |
42 | debugs(54, 5, HERE << "shm_open: " << xstrerror()); |
43 | fatal("Ipc::Mem::Segment::create failed to shm_open"); | |
f5eef98c DK |
44 | } |
45 | ||
46 | if (ftruncate(theFD, aSize)) { | |
d8a82533 AR |
47 | debugs(54, 5, HERE << "ftruncate: " << xstrerror()); |
48 | fatal("Ipc::Mem::Segment::create failed to ftruncate"); | |
f5eef98c DK |
49 | } |
50 | ||
51 | theSize = aSize; | |
937d0d3f | 52 | theReserved = 0; |
f5eef98c DK |
53 | |
54 | attach(); | |
55 | } | |
56 | ||
57 | void | |
d8a82533 | 58 | Ipc::Mem::Segment::open() |
f5eef98c DK |
59 | { |
60 | assert(theFD < 0); | |
61 | ||
62 | theFD = shm_open(theName.termedBuf(), O_RDWR, 0); | |
63 | if (theFD < 0) { | |
d8a82533 AR |
64 | debugs(54, 5, HERE << "shm_open: " << xstrerror()); |
65 | String s = "Ipc::Mem::Segment::open failed to shm_open"; | |
f1eaa254 DK |
66 | s.append(theName); |
67 | fatal(s.termedBuf()); | |
f5eef98c DK |
68 | } |
69 | ||
70 | { | |
71 | struct stat s; | |
72 | memset(&s, 0, sizeof(s)); | |
73 | if (fstat(theFD, &s)) { | |
d8a82533 AR |
74 | debugs(54, 5, HERE << "fstat: " << xstrerror()); |
75 | String s = "Ipc::Mem::Segment::open failed to fstat"; | |
f1eaa254 DK |
76 | s.append(theName); |
77 | fatal(s.termedBuf()); | |
f5eef98c DK |
78 | } |
79 | ||
80 | theSize = s.st_size; | |
81 | } | |
82 | ||
83 | attach(); | |
84 | } | |
85 | ||
86 | /// Map the shared memory segment to the process memory space. | |
87 | void | |
d8a82533 | 88 | Ipc::Mem::Segment::attach() |
f5eef98c DK |
89 | { |
90 | assert(theFD >= 0); | |
f5eef98c DK |
91 | assert(!theMem); |
92 | ||
93 | void *const p = | |
94 | mmap(NULL, theSize, PROT_READ | PROT_WRITE, MAP_SHARED, theFD, 0); | |
95 | if (p == MAP_FAILED) { | |
d8a82533 AR |
96 | debugs(54, 5, HERE << "mmap: " << xstrerror()); |
97 | fatal("Ipc::Mem::Segment::attach failed to mmap"); | |
f5eef98c DK |
98 | } |
99 | theMem = p; | |
100 | } | |
101 | ||
102 | /// Unmap the shared memory segment from the process memory space. | |
103 | void | |
d8a82533 | 104 | Ipc::Mem::Segment::detach() |
f5eef98c DK |
105 | { |
106 | if (!theMem) | |
107 | return; | |
108 | ||
109 | if (munmap(theMem, theSize)) { | |
d8a82533 AR |
110 | debugs(54, 5, HERE << "munmap: " << xstrerror()); |
111 | fatal("Ipc::Mem::Segment::detach failed to munmap"); | |
f5eef98c DK |
112 | } |
113 | theMem = 0; | |
114 | } | |
115 | ||
937d0d3f AR |
116 | void * |
117 | Ipc::Mem::Segment::reserve(size_t chunkSize) | |
118 | { | |
119 | assert(chunkSize <= theSize); | |
120 | assert(theReserved <= theSize - chunkSize); | |
121 | theReserved += chunkSize; | |
122 | return reinterpret_cast<char*>(mem()) + theReserved; | |
123 | } | |
124 | ||
9a51593d | 125 | /// Generate name for shared memory segment. Replaces all slashes with dots. |
f5eef98c | 126 | String |
d8a82533 | 127 | Ipc::Mem::Segment::GenerateName(const char *id) |
f5eef98c DK |
128 | { |
129 | String name("/squid-"); | |
9a51593d DK |
130 | for (const char *slash = strchr(id, '/'); slash; slash = strchr(id, '/')) { |
131 | if (id != slash) { | |
132 | name.append(id, slash - id); | |
133 | name.append('.'); | |
134 | } | |
135 | id = slash + 1; | |
136 | } | |
f5eef98c | 137 | name.append(id); |
f5eef98c DK |
138 | return name; |
139 | } |