]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Pointer.h
2 * Copyright (C) 1996-2016 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
);
40 /// Raw access; handy to finalize initiatization, but avoid if possible.
41 Class
*object() { return theObject
; }
44 Owner(const char *const id
, const off_t sharedSize
);
48 Owner
&operator =(const Owner
&);
50 Segment theSegment
; ///< shared memory segment that holds the object
51 Class
*theObject
; ///< shared object
54 template <class Class
> class Pointer
;
56 /// attaches to a shared memory segment with Class object owned by Owner
57 template <class Class
>
58 class Object
: public RefCountable
61 static Pointer
<Class
> Old(const char *const id
);
64 explicit Object(const char *const id
);
67 Object(const Object
&);
68 Object
&operator =(const Object
&);
70 Segment theSegment
; ///< shared memory segment that holds the object
71 Class
*theObject
; ///< shared object
73 friend class Pointer
<Class
>;
76 /// uses a refcounted pointer to Object<Class> as a parent, but
77 /// translates its API to return raw Class pointers
78 template <class Class
>
79 class Pointer
: public RefCount
< Object
<Class
> >
82 typedef RefCount
< Object
<Class
> > Base
;
85 explicit Pointer(Object
<Class
> *const anObject
= NULL
): Base(anObject
) {}
87 Class
*operator ->() const { return Base::operator ->()->theObject
; }
88 Class
&operator *() const { return *Base::operator *().theObject
; }
89 const Class
*getRaw() const { return Base::getRaw()->theObject
; }
90 Class
*getRaw() { return Base::getRaw()->theObject
; }
93 // Owner implementation
95 template <class Class
>
96 Owner
<Class
>::Owner(const char *const id
, const off_t sharedSize
):
97 theSegment(id
), theObject(NULL
)
99 theSegment
.create(sharedSize
);
100 Must(theSegment
.mem());
103 template <class Class
>
104 Owner
<Class
>::~Owner()
110 template <class Class
>
112 Owner
<Class
>::New(const char *const id
)
114 const off_t sharedSize
= Class::SharedMemorySize();
115 Owner
*const owner
= new Owner(id
, sharedSize
);
116 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class
;
120 template <class Class
> template <class P1
>
122 Owner
<Class
>::New(const char *const id
, const P1
&p1
)
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
);
130 template <class Class
> template <class P1
, class P2
>
132 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
)
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
);
140 template <class Class
> template <class P1
, class P2
, class P3
>
142 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
)
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
);
150 template <class Class
> template <class P1
, class P2
, class P3
, class P4
>
152 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
)
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
);
160 // Object implementation
162 template <class Class
>
163 Object
<Class
>::Object(const char *const id
): theSegment(id
)
166 Must(theSegment
.mem());
167 theObject
= reinterpret_cast<Class
*>(theSegment
.mem());
168 Must(static_cast<off_t
>(theObject
->sharedMemorySize()) <= theSegment
.size());
171 template <class Class
>
173 Object
<Class
>::Old(const char *const id
)
175 return Pointer
<Class
>(new Object(id
));
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
186 #endif /* SQUID_IPC_MEM_POINTER_H */