1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*++
6
7
8
9Module Name:
10
11 shmobject.hpp
12
13Abstract:
14 Shared memory based object
15
16
17
18--*/
19
20#ifndef _PAL_SHMOBJECT_HPP
21#define _PAL_SHMOBJECT_HPP
22
23#include "palobjbase.hpp"
24#include "pal/shm.hpp"
25
26extern "C"
27{
28#include "pal/list.h"
29}
30
31namespace CorUnix
32{
33 class CSimpleSharedMemoryLock : public IDataLock
34 {
35 public:
36
37 void
38 AcquireLock(
39 CPalThread *pthr,
40 IDataLock **ppDataLock
41 )
42 {
43 SHMLock();
44 *ppDataLock = static_cast<IDataLock*>(this);
45 };
46
47 virtual
48 void
49 ReleaseLock(
50 CPalThread *pthr,
51 bool fDataChanged
52 )
53 {
54 SHMRelease();
55 };
56 };
57
58 typedef struct _SHMObjData
59 {
60 SHMPTR shmPrevObj;
61 SHMPTR shmNextObj;
62 BOOL fAddedToList;
63
64 SHMPTR shmObjName;
65 SHMPTR shmObjImmutableData;
66 SHMPTR shmObjSharedData;
67
68 OBJECT_IMMUTABLE_DATA_COPY_ROUTINE pCopyRoutine;
69 OBJECT_IMMUTABLE_DATA_CLEANUP_ROUTINE pCleanupRoutine;
70
71 LONG lProcessRefCount;
72 DWORD dwNameLength;
73
74 PalObjectTypeId eTypeId;
75
76 PVOID pvSynchData;
77 } SHMObjData;
78
79 class CSharedMemoryObject : public CPalObjectBase
80 {
81 template <class T> friend void InternalDelete(T *p);
82
83 protected:
84
85 //
86 // Entry on the process's named or anonymous object list
87 //
88
89 LIST_ENTRY m_le;
90
91 //
92 // The lock that guards access to that list
93 //
94
95 CRITICAL_SECTION *m_pcsObjListLock;
96
97 //
98 // The SHMObjData for this object, protected by the
99 // shared memory lock.
100 //
101
102 SHMPTR m_shmod;
103
104 //
105 // The shared data (i.e., m_shmObjData->shmObjSharedData)
106 // for this object, mapped into this process. This will be
107 // NULL if m_pot->dwSharedDataSize is 0. Access to this data
108 // is controlled by m_ssmlSharedData when m_ObjectDomain is
109 // SharedObject, and m_sdlSharedData when it is ProcessLocalObject.
110 //
111
112 VOID *m_pvSharedData;
113
114 CSimpleSharedMemoryLock m_ssmlSharedData;
115 CSimpleDataLock m_sdlSharedData;
116
117 //
118 // Is this object process local or shared?
119 //
120
121 ObjectDomain m_ObjectDomain;
122
123 //
124 // m_fSharedDataDereferenced will be TRUE if DereferenceSharedData
125 // has already been called. (N.B. -- this is a LONG instead of a bool
126 // because it is passed to InterlockedExchange). If the shared data blob
127 // should be freed in the object's destructor DereferenceSharedData will
128 // set m_fDeleteSharedData to TRUE.
129 //
130
131 LONG m_fSharedDataDereferenced;
132 LONG m_fDeleteSharedData;
133
134 PAL_ERROR
135 AllocateSharedDataItems(
136 SHMPTR *pshmObjData,
137 SHMObjData **ppsmod
138 );
139
140 static
141 void
142 FreeSharedDataAreas(
143 SHMPTR shmObjData
144 );
145
146 bool
147 DereferenceSharedData();
148
149 virtual
150 void
151 AcquireObjectDestructionLock(
152 CPalThread *pthr
153 );
154
155 virtual
156 bool
157 ReleaseObjectDestructionLock(
158 CPalThread *pthr,
159 bool fDestructionPending
160 );
161
162 virtual ~CSharedMemoryObject();
163
164 public:
165
166 //
167 // Constructor used for new object
168 //
169
170 CSharedMemoryObject(
171 CObjectType *pot,
172 CRITICAL_SECTION *pcsObjListLock
173 )
174 :
175 CPalObjectBase(pot),
176 m_pcsObjListLock(pcsObjListLock),
177 m_shmod(NULL),
178 m_pvSharedData(NULL),
179 m_ObjectDomain(ProcessLocalObject),
180 m_fSharedDataDereferenced(FALSE),
181 m_fDeleteSharedData(FALSE)
182 {
183 InitializeListHead(&m_le);
184 };
185
186 //
187 // Constructor used to import a shared object into this process. The
188 // shared memory lock must be held when calling this contstructor
189 //
190
191 CSharedMemoryObject(
192 CObjectType *pot,
193 CRITICAL_SECTION *pcsObjListLock,
194 SHMPTR shmSharedObjectData,
195 SHMObjData *psmod,
196 bool fAddRefSharedData
197 )
198 :
199 CPalObjectBase(pot),
200 m_pcsObjListLock(pcsObjListLock),
201 m_shmod(shmSharedObjectData),
202 m_pvSharedData(NULL),
203 m_ObjectDomain(SharedObject),
204 m_fSharedDataDereferenced(FALSE),
205 m_fDeleteSharedData(FALSE)
206 {
207 InitializeListHead(&m_le);
208 if (fAddRefSharedData)
209 {
210 psmod->lProcessRefCount += 1;
211 }
212 };
213
214 virtual
215 PAL_ERROR
216 Initialize(
217 CPalThread *pthr,
218 CObjectAttributes *poa
219 );
220
221 virtual
222 PAL_ERROR
223 InitializeFromExistingSharedData(
224 CPalThread *pthr,
225 CObjectAttributes *poa
226 );
227
228 void
229 CleanupForProcessShutdown(
230 CPalThread *pthr
231 );
232
233 SHMPTR
234 GetShmObjData(
235 void
236 )
237 {
238 return m_shmod;
239 };
240
241 PLIST_ENTRY
242 GetObjectListLink(
243 void
244 )
245 {
246 return &m_le;
247 }
248
249 //
250 // Clients of this object -- in particular, CSharedMemoryObjectManager
251 // -- can't use CONTAINING_RECORD directly, since they don't have
252 // access to m_Link.
253 //
254
255 static
256 CSharedMemoryObject*
257 GetObjectFromListLink(PLIST_ENTRY pLink);
258
259 //
260 // IPalObject routines
261 //
262
263 virtual
264 PAL_ERROR
265 GetSharedData(
266 CPalThread *pthr,
267 LockType eLockRequest,
268 IDataLock **ppDataLock,
269 void **ppvSharedData
270 );
271
272 virtual
273 PAL_ERROR
274 GetSynchStateController(
275 CPalThread *pthr,
276 ISynchStateController **ppStateController
277 );
278
279 virtual
280 PAL_ERROR
281 GetSynchWaitController(
282 CPalThread *pthr,
283 ISynchWaitController **ppWaitController
284 );
285
286 virtual
287 ObjectDomain
288 GetObjectDomain(
289 void
290 );
291
292 virtual
293 PAL_ERROR
294 GetObjectSynchData(
295 VOID **ppvSynchData
296 );
297
298 };
299
300 class CSharedMemoryWaitableObject : public CSharedMemoryObject
301 {
302 template <class T> friend void InternalDelete(T *p);
303
304 protected:
305
306 VOID *m_pvSynchData;
307
308 virtual ~CSharedMemoryWaitableObject();
309
310 public:
311
312 CSharedMemoryWaitableObject(
313 CObjectType *pot,
314 CRITICAL_SECTION *pcsObjListLock
315 )
316 :
317 CSharedMemoryObject(pot, pcsObjListLock),
318 m_pvSynchData(NULL)
319 {
320 };
321
322 //
323 // Constructor used to import a shared object into this process. The
324 // shared memory lock must be held when calling this contstructor
325 //
326
327 CSharedMemoryWaitableObject(
328 CObjectType *pot,
329 CRITICAL_SECTION *pcsObjListLock,
330 SHMPTR shmSharedObjectData,
331 SHMObjData *psmod,
332 bool fAddRefSharedData
333 )
334 :
335 CSharedMemoryObject(pot, pcsObjListLock, shmSharedObjectData, psmod, fAddRefSharedData),
336 m_pvSynchData(psmod->pvSynchData)
337 {
338 };
339
340 virtual
341 PAL_ERROR
342 Initialize(
343 CPalThread *pthr,
344 CObjectAttributes *poa
345 );
346
347 //
348 // IPalObject routines
349 //
350
351 virtual
352 PAL_ERROR
353 GetSynchStateController(
354 CPalThread *pthr,
355 ISynchStateController **ppStateController
356 );
357
358 virtual
359 PAL_ERROR
360 GetSynchWaitController(
361 CPalThread *pthr,
362 ISynchWaitController **ppWaitController
363 );
364
365 virtual
366 PAL_ERROR
367 GetObjectSynchData(
368 VOID **ppvSynchData
369 );
370 };
371
372}
373
374#endif // _PAL_SHMOBJECT_HPP
375
376