]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Pointer.h
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_IPC_MEM_POINTER_H
10 #define SQUID_IPC_MEM_POINTER_H
12 #include "base/RefCount.h"
13 #include "base/TextException.h"
14 #include "ipc/mem/Segment.h"
22 /// allocates/deallocates shared memory; creates and later destroys a
23 /// Class object using that memory
24 template <class Class
>
28 static Owner
*New(const char *const id
);
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
);
37 /// attaches to the existing shared memory segment, becoming its owner
38 static Owner
*Old(const char *const id
);
42 /// Raw access; handy to finalize initiatization, but avoid if possible.
43 Class
*object() { return theObject
; }
46 explicit Owner(const char *const id
);
47 Owner(const char *const id
, const off_t sharedSize
);
51 Owner
&operator =(const Owner
&);
53 Segment theSegment
; ///< shared memory segment that holds the object
54 Class
*theObject
; ///< shared object
57 template <class Class
> class Pointer
;
59 /// attaches to a shared memory segment with Class object owned by Owner
60 template <class Class
>
61 class Object
: public RefCountable
64 static Pointer
<Class
> Old(const char *const id
);
67 explicit Object(const char *const id
);
70 Object(const Object
&);
71 Object
&operator =(const Object
&);
73 Segment theSegment
; ///< shared memory segment that holds the object
74 Class
*theObject
; ///< shared object
76 friend class Pointer
<Class
>;
79 /// uses a refcounted pointer to Object<Class> as a parent, but
80 /// translates its API to return raw Class pointers
81 template <class Class
>
82 class Pointer
: public RefCount
< Object
<Class
> >
85 typedef RefCount
< Object
<Class
> > Base
;
88 explicit Pointer(Object
<Class
> *const anObject
= NULL
): Base(anObject
) {}
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
; }
96 // Owner implementation
98 template <class Class
>
99 Owner
<Class
>::Owner(const char *const id
, const off_t sharedSize
):
100 theSegment(id
), theObject(NULL
)
102 theSegment
.create(sharedSize
);
103 Must(theSegment
.mem());
106 template <class Class
>
107 Owner
<Class
>::Owner(const char *const id
):
108 theSegment(id
), theObject(nullptr)
110 theSegment
.open(true);
111 Must(theSegment
.mem());
114 template <class Class
>
115 Owner
<Class
>::~Owner()
121 template <class Class
>
123 Owner
<Class
>::Old(const char *const id
)
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());
131 template <class Class
>
133 Owner
<Class
>::New(const char *const id
)
135 const off_t sharedSize
= Class::SharedMemorySize();
136 Owner
*const owner
= new Owner(id
, sharedSize
);
137 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class
;
141 template <class Class
> template <class P1
>
143 Owner
<Class
>::New(const char *const id
, const P1
&p1
)
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
);
151 template <class Class
> template <class P1
, class P2
>
153 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
)
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
);
161 template <class Class
> template <class P1
, class P2
, class P3
>
163 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
)
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
);
171 template <class Class
> template <class P1
, class P2
, class P3
, class P4
>
173 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
)
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
);
181 // Object implementation
183 template <class Class
>
184 Object
<Class
>::Object(const char *const id
): theSegment(id
)
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());
192 template <class Class
>
194 Object
<Class
>::Old(const char *const id
)
196 return Pointer
<Class
>(new Object(id
));
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
207 #endif /* SQUID_IPC_MEM_POINTER_H */