]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Pointer.h
4 #ifndef SQUID_IPC_MEM_POINTER_H
5 #define SQUID_IPC_MEM_POINTER_H
7 #include "base/RefCount.h"
8 #include "base/TextException.h"
9 #include "ipc/mem/Segment.h"
17 /// allocates/deallocates shared memory; creates and later destroys a
18 /// Class object using that memory
19 template <class Class
>
23 static Owner
*New(const char *const id
);
25 static Owner
*New(const char *const id
, const P1
&p1
);
26 template <class P1
, class P2
>
27 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
);
28 template <class P1
, class P2
, class P3
>
29 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
);
30 template <class P1
, class P2
, class P3
, class P4
>
31 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
);
35 /// Raw access; handy to finalize initiatization, but avoid if possible.
36 Class
*object() { return theObject
; }
39 Owner(const char *const id
, const off_t sharedSize
);
43 Owner
&operator =(const Owner
&);
45 Segment theSegment
; ///< shared memory segment that holds the object
46 Class
*theObject
; ///< shared object
49 template <class Class
> class Pointer
;
51 /// attaches to a shared memory segment with Class object owned by Owner
52 template <class Class
>
53 class Object
: public RefCountable
56 static Pointer
<Class
> Old(const char *const id
);
59 explicit Object(const char *const id
);
62 Object(const Object
&);
63 Object
&operator =(const Object
&);
65 Segment theSegment
; ///< shared memory segment that holds the object
66 Class
*theObject
; ///< shared object
68 friend class Pointer
<Class
>;
71 /// uses a refcounted pointer to Object<Class> as a parent, but
72 /// translates its API to return raw Class pointers
73 template <class Class
>
74 class Pointer
: public RefCount
< Object
<Class
> >
77 typedef RefCount
< Object
<Class
> > Base
;
80 explicit Pointer(Object
<Class
> *const anObject
= NULL
): Base(anObject
) {}
82 Class
*operator ->() const { return Base::operator ->()->theObject
; }
83 Class
&operator *() const { return *Base::operator *().theObject
; }
84 const Class
*getRaw() const { return Base::getRaw()->theObject
; }
85 Class
*getRaw() { return Base::getRaw()->theObject
; }
88 // Owner implementation
90 template <class Class
>
91 Owner
<Class
>::Owner(const char *const id
, const off_t sharedSize
):
92 theSegment(id
), theObject(NULL
)
94 theSegment
.create(sharedSize
);
95 Must(theSegment
.mem());
98 template <class Class
>
99 Owner
<Class
>::~Owner()
105 template <class Class
>
107 Owner
<Class
>::New(const char *const id
)
109 const off_t sharedSize
= Class::SharedMemorySize();
110 Owner
*const owner
= new Owner(id
, sharedSize
);
111 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class
;
115 template <class Class
> template <class P1
>
117 Owner
<Class
>::New(const char *const id
, const P1
&p1
)
119 const off_t sharedSize
= Class::SharedMemorySize(p1
);
120 Owner
*const owner
= new Owner(id
, sharedSize
);
121 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
);
125 template <class Class
> template <class P1
, class P2
>
127 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
)
129 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
);
130 Owner
*const owner
= new Owner(id
, sharedSize
);
131 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
);
135 template <class Class
> template <class P1
, class P2
, class P3
>
137 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
)
139 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
, p3
);
140 Owner
*const owner
= new Owner(id
, sharedSize
);
141 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
, p3
);
145 template <class Class
> template <class P1
, class P2
, class P3
, class P4
>
147 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
)
149 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
, p3
, p4
);
150 Owner
*const owner
= new Owner(id
, sharedSize
);
151 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
, p3
, p4
);
155 // Object implementation
157 template <class Class
>
158 Object
<Class
>::Object(const char *const id
): theSegment(id
)
161 Must(theSegment
.mem());
162 theObject
= reinterpret_cast<Class
*>(theSegment
.mem());
163 Must(static_cast<off_t
>(theObject
->sharedMemorySize()) == theSegment
.size());
166 template <class Class
>
168 Object
<Class
>::Old(const char *const id
)
170 return Pointer
<Class
>(new Object(id
));
173 // convenience macros for creating shared objects
174 #define shm_new(Class) Ipc::Mem::Owner<Class>::New
175 #define shm_old(Class) Ipc::Mem::Object<Class>::Old
181 #endif /* SQUID_IPC_MEM_POINTER_H */