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 | |
9 | Module Name: |
10 | |
11 | shmobject.hpp |
12 | |
13 | Abstract: |
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 | |
26 | extern "C" |
27 | { |
28 | #include "pal/list.h" |
29 | } |
30 | |
31 | namespace 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 | |