]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Pointer.h
6 #ifndef SQUID_IPC_MEM_POINTER_H
7 #define SQUID_IPC_MEM_POINTER_H
9 #include "base/TextException.h"
10 #include "ipc/mem/Segment.h"
19 /// allocates/deallocates shared memory; creates and later destroys a
20 /// Class object using that memory
21 template <class Class
>
25 static Owner
*New(const char *const id
);
27 static Owner
*New(const char *const id
, const P1
&p1
);
28 template <class P1
, class P2
>
29 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
);
30 template <class P1
, class P2
, class P3
>
31 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
);
32 template <class P1
, class P2
, class P3
, class P4
>
33 static Owner
*New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
);
38 Owner(const char *const id
, const off_t sharedSize
);
42 Owner
&operator =(const Owner
&);
44 Segment theSegment
; ///< shared memory segment that holds the object
45 Class
*theObject
; ///< shared object
48 template <class Class
> class Pointer
;
50 /// attaches to a shared memory segment with Class object owned by Owner
51 template <class Class
>
52 class Object
: public RefCountable
55 static Pointer
<Class
> Old(const char *const id
);
58 explicit Object(const char *const id
);
61 Object(const Object
&);
62 Object
&operator =(const Object
&);
64 Segment theSegment
; ///< shared memory segment that holds the object
65 Class
*theObject
; ///< shared object
67 friend class Pointer
<Class
>;
70 /// uses a refcounted pointer to Object<Class> as a parent, but
71 /// translates its API to return raw Class pointers
72 template <class Class
>
73 class Pointer
: public RefCount
< Object
<Class
> >
76 typedef RefCount
< Object
<Class
> > Base
;
79 explicit Pointer(Object
<Class
> *const anObject
= NULL
): Base(anObject
) {}
81 Class
*operator ->() const { return Base::operator ->()->theObject
; }
82 Class
&operator *() const { return *Base::operator *().theObject
; }
83 const Class
*getRaw() const { return Base::getRaw()->theObject
; }
84 Class
*getRaw() { return Base::getRaw()->theObject
; }
87 // Owner implementation
89 template <class Class
>
90 Owner
<Class
>::Owner(const char *const id
, const off_t sharedSize
):
91 theSegment(id
), theObject(NULL
)
93 theSegment
.create(sharedSize
);
94 Must(theSegment
.mem());
97 template <class Class
>
98 Owner
<Class
>::~Owner()
104 template <class Class
>
106 Owner
<Class
>::New(const char *const id
)
108 const off_t sharedSize
= Class::SharedMemorySize();
109 Owner
*const owner
= new Owner(id
, sharedSize
);
110 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class
;
114 template <class Class
> template <class P1
>
116 Owner
<Class
>::New(const char *const id
, const P1
&p1
)
118 const off_t sharedSize
= Class::SharedMemorySize(p1
);
119 Owner
*const owner
= new Owner(id
, sharedSize
);
120 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
);
124 template <class Class
> template <class P1
, class P2
>
126 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
)
128 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
);
129 Owner
*const owner
= new Owner(id
, sharedSize
);
130 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
);
134 template <class Class
> template <class P1
, class P2
, class P3
>
136 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
)
138 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
, p3
);
139 Owner
*const owner
= new Owner(id
, sharedSize
);
140 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
, p3
);
144 template <class Class
> template <class P1
, class P2
, class P3
, class P4
>
146 Owner
<Class
>::New(const char *const id
, const P1
&p1
, const P2
&p2
, const P3
&p3
, const P4
&p4
)
148 const off_t sharedSize
= Class::SharedMemorySize(p1
, p2
, p3
, p4
);
149 Owner
*const owner
= new Owner(id
, sharedSize
);
150 owner
->theObject
= new (owner
->theSegment
.reserve(sharedSize
)) Class(p1
, p2
, p3
, p4
);
154 // Object implementation
156 template <class Class
>
157 Object
<Class
>::Object(const char *const id
): theSegment(id
)
160 Must(theSegment
.mem());
161 theObject
= reinterpret_cast<Class
*>(theSegment
.mem());
162 Must(static_cast<off_t
>(theObject
->sharedMemorySize()) == theSegment
.size());
165 template <class Class
>
167 Object
<Class
>::Old(const char *const id
)
169 return Pointer
<Class
>(new Object(id
));
172 // convenience macros for creating shared objects
173 #define shm_new(Class) Ipc::Mem::Owner<Class>::New
174 #define shm_old(Class) Ipc::Mem::Object<Class>::Old
180 #endif /* SQUID_IPC_MEM_POINTER_H */