Pointer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_SRC_IPC_MEM_POINTER_H
10 #define SQUID_SRC_IPC_MEM_POINTER_H
11 
12 #include "base/RefCount.h"
13 #include "base/TextException.h"
14 #include "ipc/mem/Segment.h"
15 
16 namespace Ipc
17 {
18 
19 namespace Mem
20 {
21 
24 template <class Class>
25 class Owner
26 {
27 public:
28  static Owner *New(const char *const id);
29  template <class P1>
30  static Owner *New(const char *const id, const P1 &p1);
31  template <class P1, class P2>
32  static Owner *New(const char *const id, const P1 &p1, const P2 &p2);
33  template <class P1, class P2, class P3>
34  static Owner *New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3);
35  template <class P1, class P2, class P3, class P4>
36  static Owner *New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4);
38  static Owner *Old(const char *const id);
39 
40  ~Owner();
41 
43  Class *object() { return theObject; }
44 
45 private:
46  explicit Owner(const char *const id);
47  Owner(const char *const id, const off_t sharedSize);
48 
49  // not implemented
50  Owner(const Owner &);
51  Owner &operator =(const Owner &);
52 
54  Class *theObject;
55 };
56 
57 template <class Class> class Pointer;
58 
60 template <class Class>
61 class Object: public RefCountable
62 {
63 public:
64  static Pointer<Class> Old(const char *const id);
65 
66 private:
67  explicit Object(const char *const id);
68 
69  // not implemented
70  Object(const Object &);
71  Object &operator =(const Object &);
72 
74  Class *theObject;
75 
76  friend class Pointer<Class>;
77 };
78 
81 template <class Class>
82 class Pointer: public RefCount< Object<Class> >
83 {
84 private:
86 
87 public:
88  explicit Pointer(Object<Class> *const anObject = nullptr): Base(anObject) {}
89 
90  Class *operator ->() const { return Base::operator ->()->theObject; }
91  Class &operator *() const { return *Base::operator *().theObject; }
92  const Class *getRaw() const { return Base::getRaw()->theObject; }
93  Class *getRaw() { return Base::getRaw()->theObject; }
94 };
95 
96 // Owner implementation
97 
98 template <class Class>
99 Owner<Class>::Owner(const char *const id, const off_t sharedSize):
100  theSegment(id), theObject(nullptr)
101 {
102  theSegment.create(sharedSize);
103  Must(theSegment.mem());
104 }
105 
106 template <class Class>
107 Owner<Class>::Owner(const char *const id):
108  theSegment(id), theObject(nullptr)
109 {
110  theSegment.open(true);
111  Must(theSegment.mem());
112 }
113 
114 template <class Class>
116 {
117  if (theObject)
118  theObject->~Class();
119 }
120 
121 template <class Class>
122 Owner<Class> *
123 Owner<Class>::Old(const char *const id)
124 {
125  auto owner = new Owner(id);
126  owner->theObject = reinterpret_cast<Class*>(owner->theSegment.mem());
127  Must(static_cast<off_t>(owner->theObject->sharedMemorySize()) <= owner->theSegment.size());
128  return owner;
129 }
130 
131 template <class Class>
132 Owner<Class> *
133 Owner<Class>::New(const char *const id)
134 {
135  const off_t sharedSize = Class::SharedMemorySize();
136  Owner *const owner = new Owner(id, sharedSize);
137  owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class;
138  return owner;
139 }
140 
141 template <class Class> template <class P1>
142 Owner<Class> *
143 Owner<Class>::New(const char *const id, const P1 &p1)
144 {
145  const off_t sharedSize = Class::SharedMemorySize(p1);
146  Owner *const owner = new Owner(id, sharedSize);
147  owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1);
148  return owner;
149 }
150 
151 template <class Class> template <class P1, class P2>
152 Owner<Class> *
153 Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2)
154 {
155  const off_t sharedSize = Class::SharedMemorySize(p1, p2);
156  Owner *const owner = new Owner(id, sharedSize);
157  owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2);
158  return owner;
159 }
160 
161 template <class Class> template <class P1, class P2, class P3>
162 Owner<Class> *
163 Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3)
164 {
165  const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3);
166  Owner *const owner = new Owner(id, sharedSize);
167  owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3);
168  return owner;
169 }
170 
171 template <class Class> template <class P1, class P2, class P3, class P4>
172 Owner<Class> *
173 Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
174 {
175  const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3, p4);
176  Owner *const owner = new Owner(id, sharedSize);
177  owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3, p4);
178  return owner;
179 }
180 
181 // Object implementation
182 
183 template <class Class>
184 Object<Class>::Object(const char *const id): theSegment(id)
185 {
186  theSegment.open(false);
187  Must(theSegment.mem());
188  theObject = reinterpret_cast<Class*>(theSegment.mem());
189  Must(static_cast<off_t>(theObject->sharedMemorySize()) <= theSegment.size());
190 }
191 
192 template <class Class>
194 Object<Class>::Old(const char *const id)
195 {
196  return Pointer<Class>(new Object(id));
197 }
198 
199 // convenience macros for creating shared objects
200 #define shm_new(Class) Ipc::Mem::Owner<Class>::New
201 #define shm_old(Class) Ipc::Mem::Object<Class>::Old
202 
203 } // namespace Mem
204 
205 } // namespace Ipc
206 
207 #endif /* SQUID_SRC_IPC_MEM_POINTER_H */
208 
C * operator->() const
Definition: RefCount.h:82
Object & operator=(const Object &)
Class * operator->() const
Definition: Pointer.h:90
RefCount< Object< Class > > Base
Definition: Pointer.h:85
Class * theObject
shared object
Definition: Pointer.h:54
C * getRaw() const
Definition: RefCount.h:89
static Pointer< Class > Old(const char *const id)
Definition: Pointer.h:194
Class * theObject
shared object
Definition: Pointer.h:74
Memory Management.
Definition: Allocator.h:16
Segment theSegment
shared memory segment that holds the object
Definition: Pointer.h:53
void * reserve(size_t chunkSize)
reserve and return the next chunk
Definition: Segment.cc:38
Pointer(Object< Class > *const anObject=nullptr)
Definition: Pointer.h:88
attaches to a shared memory segment with Class object owned by Owner
Definition: Pointer.h:61
static Owner * Old(const char *const id)
attaches to the existing shared memory segment, becoming its owner
Definition: Pointer.h:123
POSIX shared memory segment.
Definition: Segment.h:23
void open(const bool unlinkWhenDone)
Definition: Segment.cc:346
Owner & operator=(const Owner &)
Object(const char *const id)
Definition: Pointer.h:184
Segment theSegment
shared memory segment that holds the object
Definition: Pointer.h:73
#define Must(condition)
Definition: TextException.h:75
static Owner * New(const char *const id)
Definition: Pointer.h:133
Class * getRaw()
Definition: Pointer.h:93
Owner(const char *const id)
Definition: Pointer.h:107
Class & operator*() const
Definition: Pointer.h:91
C & operator*() const
Definition: RefCount.h:84
Class * object()
Raw access; handy to finalize initiatization, but avoid if possible.
Definition: Pointer.h:43
const Class * getRaw() const
Definition: Pointer.h:92
Definition: IpcIoFile.h:23

 

Introduction

Documentation

Support

Miscellaneous