ReactOS 0.4.15-dev-7924-g5949c20
fxdisposelist.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxDisposeList.hpp
8
9Abstract:
10
11 This class implements a Disposal list for deferring Dispose
12 processing from dispatch to passive level.
13
14 It works tightly with FxObject, and is a friend class.
15
16Author:
17
18
19
20
21
22
23Environment:
24
25 Both kernel and user mode
26
27Revision History:
28
29
30--*/
31
32#include "coreprivshared.hpp"
33
34#include "fxdisposelist.hpp"
35
36// Tracing support
37extern "C" {
38// #include "FxDisposeList.tmh"
39}
40
42 PFX_DRIVER_GLOBALS FxDriverGlobals
43 ) :
44 FxNonPagedObject(FX_TYPE_DISPOSELIST, 0, FxDriverGlobals)
45{
48
51}
52
54{
56}
57
60 PFX_DRIVER_GLOBALS FxDriverGlobals,
61 PVOID WdmObject,
63 )
64{
67
68 *pObject = NULL;
69
70 list = new(FxDriverGlobals) FxDisposeList(FxDriverGlobals);
71
72 if (list == NULL) {
74 }
75
76 status = list->Initialize(WdmObject);
77
78 if (NT_SUCCESS(status)) {
79 *pObject = list;
80 }
81 else {
82 list->DeleteFromFailedCreate();
83 }
84
85 return status;
86}
87
90 PVOID WdmObject
91 )
92{
94 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
95
97
98 status = FxSystemWorkItem::_Create(FxDriverGlobals,
99 WdmObject,
101 );
102 if (!NT_SUCCESS(status)) {
104 "Could not allocate workitem: %!STATUS!", status);
105 return status;
106 }
107
108 m_WdmObject = WdmObject;
109
110 return STATUS_SUCCESS;
111}
112
115 )
116{
117 if (m_SystemWorkItem != NULL) {
120 }
121
123
124 FxNonPagedObject::Dispose(); // __super call
125
126 return TRUE;
127}
128
129VOID
132 )
133
134/*++
135
136Routine Description:
137
138 Add an object to the cleanup list.
139
140
141
142
143
144
145
146 The caller is expected to manage any reference counts on
147 the object while on the cleanup list
148
149Arguments:
150
151 object - Object to cleanup at passive level
152
153Returns:
154
155 None
156
157--*/
158
159{
160 KIRQL irql;
161 BOOLEAN previouslyEmpty;
162
163 Lock(&irql);
164
165 ASSERT(Object->m_DisposeSingleEntry.Next == NULL);
166
167 previouslyEmpty = m_List.Next == NULL ? TRUE : FALSE;
168
169 //
170 // Add to the end of m_List
171 //
172 *m_ListEnd = &Object->m_DisposeSingleEntry;
173
174 //
175 // Update the end
176 //
177 m_ListEnd = &Object->m_DisposeSingleEntry.Next;
178
179 if (previouslyEmpty) {
181 }
182
183 Unlock(irql);
184}
185
186VOID
188 PKIRQL PreviousIrql
189 )
190{
193
194 //
195 // Process items on the list until it is empty
196 //
197 while (m_List.Next != NULL) {
199
200 //
201 // Remove pEntry from the list
202 //
203 m_List.Next = pEntry->Next;
204
205 //
206 // Indicate pEntry is no longer in the list
207 //
208 pEntry->Next = NULL;
209
210 //
211 // Convert back to the object
212 //
214
215 //
216 // If the list is empty, we just popped off the entry and we need to
217 // update m_ListEnd to a head of the list so it points to valid pool.
218 //
219 if (m_List.Next == NULL) {
221 }
222
223 Unlock(*PreviousIrql);
224
225 //
226 // Invoke the objects deferred dispose entry
227 //
229
230 //
231 // pObject may be invalid at this point due to its dereferencing itself
232 //
233 Lock(PreviousIrql);
234 }
235}
236
237VOID
240 )
241{
242 FxDisposeList* pThis;
243 KIRQL irql;
244
245 pThis = (FxDisposeList*) Parameter;
246
247 pThis->Lock(&irql);
248
249 pThis->DrainListLocked(&irql);
250
251 pThis->Unlock(irql);
252}
253
254VOID
256 )
257
258/*++
259
260Routine Description:
261
262 Wait until the list goes empty with no items.
263
264 Note, on wakeup, new items could have been added, only the assurance
265 is that the list at least went empty for a moment.
266
267 This allows a waiter to wait for all previous Add() items to
268 finishing processing before return.
269
270Arguments:
271
272Returns:
273
274--*/
275
276{
277 KIRQL irql;
278 BOOLEAN wait;
279
280 Lock(&irql);
281
282 wait = TRUE;
283
285
286
287
288
289
290
291
292 ASSERT(FALSE);
294 wait = FALSE;
295 }
296
297 Unlock(irql);
298
299 if (wait) {
301 }
302
303 // Should only be true for an empty list
305}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID DrainListLocked(PKIRQL PreviousIrql)
static VOID _WorkItemThunk(__in PVOID Parameter)
static NTSTATUS _Create(PFX_DRIVER_GLOBALS FxDriverGlobals, PVOID WdmObject, FxDisposeList **pObject)
VOID WaitForEmpty(VOID)
MxThread m_WorkItemThread
NTSTATUS Initialize(PVOID wdmObject)
virtual BOOLEAN Dispose(VOID)
SINGLE_LIST_ENTRY ** m_ListEnd
FxSystemWorkItem * m_SystemWorkItem
VOID Add(FxObject *object)
SINGLE_LIST_ENTRY m_List
static FxObject * _FromDisposeEntry(__in PSINGLE_LIST_ENTRY Entry)
Definition: fxobject.hpp:580
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID DeferredDisposeWorkItem(VOID)
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
friend FxDisposeList
Definition: fxobject.hpp:236
virtual BOOLEAN Dispose(VOID)
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
__inline BOOLEAN TryToEnqueue(__in PFN_WDF_SYSTEMWORKITEM CallbackFunc, __in PVOID Parameter)
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
Definition: list.h:37
#define __in
Definition: dbghelp.h:35
#define TRACINGIO
Definition: dbgtrace.h:66
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
@ ObjectDoNotLock
Definition: fxobject.hpp:128
FxObject * pObject
@ FX_TYPE_DISPOSELIST
Definition: fxtypes.h:86
#define ASSERT(a)
Definition: mode.c:44
#define list
Definition: rosglue.h:35
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: ps.c:97
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323