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