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 // Minimal Crst implementation based on CRITICAL_SECTION. Doesn't support much except for the basic locking 9 // functionality (in particular there is no rank violation checking). 10 // 11 12 enum CrstType 13 { 14 CrstHandleTable, 15 CrstDispatchCache, 16 CrstAllocHeap, 17 CrstGenericInstHashtab, 18 CrstMemAccessMgr, 19 CrstInterfaceDispatchGlobalLists, 20 CrstStressLog, 21 CrstRestrictedCallouts, 22 CrstGcStressControl, 23 CrstSuspendEE, 24 CrstCastCache, 25 }; 26 27 enum CrstFlags 28 { 29 CRST_DEFAULT = 0x0, 30 CRST_REENTRANCY = 0x0, 31 CRST_UNSAFE_SAMELEVEL = 0x0, 32 CRST_UNSAFE_ANYMODE = 0x0, 33 CRST_DEBUGGER_THREAD = 0x0, 34 }; 35 36 // Static version of Crst with no default constructor (user must call Init() before use). 37 class CrstStatic 38 { 39 public: 40 void Init(CrstType eType, CrstFlags eFlags = CRST_DEFAULT); 41 bool InitNoThrow(CrstType eType, CrstFlags eFlags = CRST_DEFAULT) { Init(eType, eFlags); return true; } 42 void Destroy(); Enter()43 void Enter() { CrstStatic::Enter(this); } Leave()44 void Leave() { CrstStatic::Leave(this); } 45 static void Enter(CrstStatic *pCrst); 46 static void Leave(CrstStatic *pCrst); 47 #if defined(_DEBUG) 48 bool OwnedByCurrentThread(); 49 EEThreadId GetHolderThreadId(); 50 #endif // _DEBUG 51 52 private: 53 CRITICAL_SECTION m_sCritSec; 54 #if defined(_DEBUG) 55 EEThreadId m_uiOwnerId; 56 #endif // _DEBUG 57 }; 58 59 // Non-static version that will initialize itself during construction. 60 class Crst : public CrstStatic 61 { 62 public: 63 Crst(CrstType eType, CrstFlags eFlags = CRST_DEFAULT) CrstStatic()64 : CrstStatic() 65 { Init(eType, eFlags); } 66 }; 67 68 // Holder for a Crst instance. 69 class CrstHolder 70 { 71 CrstStatic * m_pLock; 72 73 public: CrstHolder(CrstStatic * pLock)74 CrstHolder(CrstStatic * pLock) 75 : m_pLock(pLock) 76 { 77 m_pLock->Enter(); 78 } 79 ~CrstHolder()80 ~CrstHolder() 81 { 82 m_pLock->Leave(); 83 } 84 }; 85 86 class CrstHolderWithState 87 { 88 CrstStatic * m_pLock; 89 bool m_fAcquired; 90 91 public: 92 CrstHolderWithState(CrstStatic * pLock, bool fAcquire = true) m_pLock(pLock)93 : m_pLock(pLock), m_fAcquired(fAcquire) 94 { 95 if (fAcquire) 96 m_pLock->Enter(); 97 } 98 ~CrstHolderWithState()99 ~CrstHolderWithState() 100 { 101 if (m_fAcquired) 102 m_pLock->Leave(); 103 } 104 Acquire()105 void Acquire() 106 { 107 if (!m_fAcquired) 108 { 109 m_pLock->Enter(); 110 m_fAcquired = true; 111 } 112 } 113 Release()114 void Release() 115 { 116 if (m_fAcquired) 117 { 118 m_pLock->Leave(); 119 m_fAcquired = false; 120 } 121 } 122 GetValue()123 CrstStatic * GetValue() 124 { 125 return m_pLock; 126 } 127 }; 128