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_IPC_MEM_POINTER_H
10#define SQUID_IPC_MEM_POINTER_H
11
12#include "base/RefCount.h"
13#include "base/TextException.h"
14#include "ipc/mem/Segment.h"
15
16namespace Ipc
17{
18
19namespace Mem
20{
21
24template <class Class>
25class Owner
26{
27public:
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
41
43 Class *object() { return theObject; }
44
45private:
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 &);
52
54 Class *theObject;
55};
56
57template <class Class> class Pointer;
58
60template <class Class>
61class Object: public RefCountable
62{
63public:
64 static Pointer<Class> Old(const char *const id);
65
66private:
67 explicit Object(const char *const id);
68
69 // not implemented
70 Object(const Object &);
72
74 Class *theObject;
75
76 friend class Pointer<Class>;
77};
78
81template <class Class>
82class Pointer: public RefCount< Object<Class> >
83{
84private:
86
87public:
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
98template <class Class>
99Owner<Class>::Owner(const char *const id, const off_t sharedSize):
100 theSegment(id), theObject(nullptr)
101{
102 theSegment.create(sharedSize);
104}
105
106template <class Class>
107Owner<Class>::Owner(const char *const id):
108 theSegment(id), theObject(nullptr)
109{
110 theSegment.open(true);
112}
113
114template <class Class>
116{
117 if (theObject)
118 theObject->~Class();
119}
120
121template <class Class>
123Owner<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
131template <class Class>
133Owner<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
141template <class Class> template <class P1>
143Owner<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
151template <class Class> template <class P1, class P2>
153Owner<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
161template <class Class> template <class P1, class P2, class P3>
163Owner<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
171template <class Class> template <class P1, class P2, class P3, class P4>
173Owner<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
183template <class Class>
184Object<Class>::Object(const char *const id): theSegment(id)
185{
186 theSegment.open(false);
188 theObject = reinterpret_cast<Class*>(theSegment.mem());
189 Must(static_cast<off_t>(theObject->sharedMemorySize()) <= theSegment.size());
190}
191
192template <class Class>
194Object<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_IPC_MEM_POINTER_H */
208
#define RefCountable
The locking interface for use on Reference-Counted classes.
Definition: Lock.h:66
#define Must(condition)
Definition: TextException.h:75
attaches to a shared memory segment with Class object owned by Owner
Definition: Pointer.h:62
Object & operator=(const Object &)
Segment theSegment
shared memory segment that holds the object
Definition: Pointer.h:73
Object(const Object &)
static Pointer< Class > Old(const char *const id)
Definition: Pointer.h:194
Class * theObject
shared object
Definition: Pointer.h:74
Object(const char *const id)
Definition: Pointer.h:184
Owner(const char *const id)
Definition: Pointer.h:107
Owner(const char *const id, const off_t sharedSize)
Definition: Pointer.h:99
Class * theObject
shared object
Definition: Pointer.h:54
static Owner * New(const char *const id)
Definition: Pointer.h:133
Segment theSegment
shared memory segment that holds the object
Definition: Pointer.h:53
static Owner * New(const char *const id, const P1 &p1, const P2 &p2)
static Owner * New(const char *const id, const P1 &p1)
Owner(const Owner &)
Owner & operator=(const Owner &)
Class * object()
Raw access; handy to finalize initiatization, but avoid if possible.
Definition: Pointer.h:43
static Owner * Old(const char *const id)
attaches to the existing shared memory segment, becoming its owner
Definition: Pointer.h:123
static Owner * New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3)
static Owner * New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
Class & operator*() const
Definition: Pointer.h:91
const Class * getRaw() const
Definition: Pointer.h:92
Class * getRaw()
Definition: Pointer.h:93
RefCount< Object< Class > > Base
Definition: Pointer.h:85
Pointer(Object< Class > *const anObject=nullptr)
Definition: Pointer.h:88
Class * operator->() const
Definition: Pointer.h:90
POSIX shared memory segment.
Definition: Segment.h:24
void open(const bool unlinkWhenDone)
Definition: Segment.cc:346
void * mem()
pointer to the next chunk
Definition: Segment.h:41
void * reserve(size_t chunkSize)
reserve and return the next chunk
Definition: Segment.cc:38
void create(const off_t aSize)
Create a new shared memory segment. Unlinks the segment on destruction.
Definition: Segment.cc:328
off_t size()
shared memory segment size
Definition: Segment.h:40
Object< Class > * operator->() const
Definition: RefCount.h:82
Object< Class > * getRaw() const
Definition: RefCount.h:89
Object< Class > & operator*() const
Definition: RefCount.h:84
Definition: IpcIoFile.h:24
Memory Management.
Definition: Allocator.h:17

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors