1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxCallbackSpinLock.hpp 8 9 Abstract: 10 11 This is the C++ header for the FxCallbackSpinLock 12 13 This is the spinlock based driver callback lock 14 15 16 Author: 17 18 19 20 21 Revision History: 22 23 24 --*/ 25 26 #ifndef _FXCALLBACKSPINLOCK_H_ 27 #define _FXCALLBACKSPINLOCK_H_ 28 29 extern "C" { 30 31 #if defined(EVENT_TRACING) 32 #include "FxCallbackSpinLock.hpp.tmh" 33 #endif 34 35 } 36 37 class FxCallbackSpinLock : public FxCallbackLock { 38 39 private: 40 MxLock m_Lock; 41 42 public: 43 FxCallbackSpinLock(PFX_DRIVER_GLOBALS FxDriverGlobals)44 FxCallbackSpinLock( 45 PFX_DRIVER_GLOBALS FxDriverGlobals 46 ) : 47 FxCallbackLock(FxDriverGlobals) 48 { 49 } 50 51 virtual ~FxCallbackSpinLock(VOID)52 ~FxCallbackSpinLock( 53 VOID 54 ) 55 { 56 if (m_Verifier) { 57 delete m_Verifier; 58 } 59 } 60 61 virtual 62 void Initialize(FxObject * ParentObject)63 Initialize( 64 FxObject* ParentObject 65 ) 66 { 67 PFX_DRIVER_GLOBALS fxDriverGlobals; 68 69 m_Verifier = NULL; 70 fxDriverGlobals = GetDriverGlobals(); 71 72 if (fxDriverGlobals->FxVerifierLock) { 73 74 // 75 // VerifierLock CreateAndInitialize failure is not fatal, 76 // we just won't track anything 77 // 78 (void) FxVerifierLock::CreateAndInitialize(&m_Verifier, 79 fxDriverGlobals, 80 ParentObject, 81 FALSE); 82 83 } 84 } 85 86 virtual 87 void Lock(__out PKIRQL PreviousIrql)88 Lock( 89 __out PKIRQL PreviousIrql 90 ) 91 { 92 MxThread cur = Mx::MxGetCurrentThread(); 93 94 if (m_OwnerThread == cur) { 95 PFX_DRIVER_GLOBALS fxDriverGlobals; 96 97 fxDriverGlobals = GetDriverGlobals(); 98 m_RecursionCount++; 99 100 // 101 // For now we have decided not to allow this. 102 // 103 104 105 106 107 108 // 109 DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_FATAL, TRACINGDEVICE, 110 "Recursive acquire of callback lock! 0x%p", this); 111 112 FxVerifierBugCheck(fxDriverGlobals, 113 WDF_RECURSIVE_LOCK, 114 (ULONG_PTR) this); 115 return; 116 } 117 else { 118 if (m_Verifier != NULL) { 119 m_Verifier->Lock(PreviousIrql, FALSE); 120 } 121 else { 122 m_Lock.Acquire(PreviousIrql); 123 } 124 125 m_OwnerThread = cur; 126 return; 127 } 128 } 129 130 virtual 131 void Unlock(__in KIRQL PreviousIrql)132 Unlock( 133 __in KIRQL PreviousIrql 134 ) 135 { 136 CheckOwnership(); 137 138 if (m_RecursionCount > 0) { 139 m_RecursionCount--; 140 } 141 else { 142 m_OwnerThread = NULL; 143 if (m_Verifier != NULL) { 144 m_Verifier->Unlock(PreviousIrql, FALSE); 145 } 146 else { 147 m_Lock.Release(PreviousIrql); 148 } 149 } 150 } 151 152 _Must_inspect_result_ 153 inline 154 virtual 155 BOOLEAN IsOwner(VOID)156 IsOwner( 157 VOID 158 ) 159 { 160 MxThread cur = Mx::MxGetCurrentThread(); 161 162 if (m_OwnerThread == cur) { 163 return TRUE; 164 } 165 else { 166 return FALSE; 167 } 168 } 169 }; 170 171 #endif // _FXCALLBACKSPINLOCK_H_ 172