]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/mem/Pointer.h
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / ipc / mem / Pointer.h
CommitLineData
68353d5a 1/*
bbc27441
AJ
2 * Copyright (C) 1996-2014 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.
68353d5a
DK
7 */
8
9#ifndef SQUID_IPC_MEM_POINTER_H
10#define SQUID_IPC_MEM_POINTER_H
11
8bf217bd 12#include "base/RefCount.h"
68353d5a
DK
13#include "base/TextException.h"
14#include "ipc/mem/Segment.h"
68353d5a 15
9199139f
AR
16namespace Ipc
17{
68353d5a 18
9199139f
AR
19namespace Mem
20{
68353d5a
DK
21
22/// allocates/deallocates shared memory; creates and later destroys a
23/// Class object using that memory
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);
f5591061
DK
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);
68353d5a
DK
37
38 ~Owner();
39
6d68a230 40 /// Raw access; handy to finalize initiatization, but avoid if possible.
93910d5c
AR
41 Class *object() { return theObject; }
42
68353d5a
DK
43private:
44 Owner(const char *const id, const off_t sharedSize);
45
46 // not implemented
47 Owner(const Owner &);
48 Owner &operator =(const Owner &);
49
50 Segment theSegment; ///< shared memory segment that holds the object
51 Class *theObject; ///< shared object
52};
53
54template <class Class> class Pointer;
55
56/// attaches to a shared memory segment with Class object owned by Owner
57template <class Class>
58class Object: public RefCountable
59{
60public:
61 static Pointer<Class> Old(const char *const id);
62
63private:
64 explicit Object(const char *const id);
65
66 // not implemented
67 Object(const Object &);
68 Object &operator =(const Object &);
69
70 Segment theSegment; ///< shared memory segment that holds the object
71 Class *theObject; ///< shared object
72
73 friend class Pointer<Class>;
74};
75
76/// uses a refcounted pointer to Object<Class> as a parent, but
77/// translates its API to return raw Class pointers
78template <class Class>
79class Pointer: public RefCount< Object<Class> >
80{
81private:
82 typedef RefCount< Object<Class> > Base;
83
84public:
f5591061 85 explicit Pointer(Object<Class> *const anObject = NULL): Base(anObject) {}
68353d5a
DK
86
87 Class *operator ->() const { return Base::operator ->()->theObject; }
88 Class &operator *() const { return *Base::operator *().theObject; }
cd43a242 89 const Class *getRaw() const { return Base::getRaw()->theObject; }
68353d5a
DK
90 Class *getRaw() { return Base::getRaw()->theObject; }
91};
92
93// Owner implementation
94
95template <class Class>
96Owner<Class>::Owner(const char *const id, const off_t sharedSize):
9199139f 97 theSegment(id), theObject(NULL)
68353d5a
DK
98{
99 theSegment.create(sharedSize);
100 Must(theSegment.mem());
101}
102
103template <class Class>
104Owner<Class>::~Owner()
105{
106 if (theObject)
107 theObject->~Class();
108}
109
110template <class Class>
111Owner<Class> *
112Owner<Class>::New(const char *const id)
113{
114 const off_t sharedSize = Class::SharedMemorySize();
115 Owner *const owner = new Owner(id, sharedSize);
116 owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class;
117 return owner;
118}
119
120template <class Class> template <class P1>
121Owner<Class> *
122Owner<Class>::New(const char *const id, const P1 &p1)
123{
124 const off_t sharedSize = Class::SharedMemorySize(p1);
125 Owner *const owner = new Owner(id, sharedSize);
126 owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1);
127 return owner;
128}
129
130template <class Class> template <class P1, class P2>
131Owner<Class> *
132Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2)
133{
134 const off_t sharedSize = Class::SharedMemorySize(p1, p2);
135 Owner *const owner = new Owner(id, sharedSize);
136 owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2);
137 return owner;
138}
139
140template <class Class> template <class P1, class P2, class P3>
141Owner<Class> *
142Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3)
143{
144 const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3);
145 Owner *const owner = new Owner(id, sharedSize);
146 owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3);
147 return owner;
148}
149
f5591061
DK
150template <class Class> template <class P1, class P2, class P3, class P4>
151Owner<Class> *
152Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
153{
154 const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3, p4);
155 Owner *const owner = new Owner(id, sharedSize);
156 owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3, p4);
157 return owner;
158}
159
68353d5a
DK
160// Object implementation
161
162template <class Class>
163Object<Class>::Object(const char *const id): theSegment(id)
164{
165 theSegment.open();
166 Must(theSegment.mem());
167 theObject = reinterpret_cast<Class*>(theSegment.mem());
168 Must(static_cast<off_t>(theObject->sharedMemorySize()) == theSegment.size());
169}
170
171template <class Class>
172Pointer<Class>
173Object<Class>::Old(const char *const id)
174{
175 return Pointer<Class>(new Object(id));
176}
177
178// convenience macros for creating shared objects
179#define shm_new(Class) Ipc::Mem::Owner<Class>::New
180#define shm_old(Class) Ipc::Mem::Object<Class>::Old
181
182} // namespace Mem
183
184} // namespace Ipc
185
186#endif /* SQUID_IPC_MEM_POINTER_H */