| 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 |  | 
|---|