xref: /reactos/sdk/include/ddk/scavengr.h (revision c2c66aff)
1*c2c66affSColin Finck #ifndef _SCAVENGR_H_
2*c2c66affSColin Finck #define _SCAVENGR_H_
3*c2c66affSColin Finck 
4*c2c66affSColin Finck extern KMUTEX RxScavengerMutex;
5*c2c66affSColin Finck 
6*c2c66affSColin Finck #define RX_SCAVENGER_FINALIZATION_TIME_INTERVAL (10 * 1000 * 1000 * 10)
7*c2c66affSColin Finck 
8*c2c66affSColin Finck typedef struct _RX_SCAVENGER_ENTRY
9*c2c66affSColin Finck {
10*c2c66affSColin Finck     LIST_ENTRY List;
11*c2c66affSColin Finck     UCHAR Type;
12*c2c66affSColin Finck     UCHAR Operation;
13*c2c66affSColin Finck     UCHAR State;
14*c2c66affSColin Finck     UCHAR Flags;
15*c2c66affSColin Finck     struct _RX_SCAVENGER_ENTRY *pContinuationEntry;
16*c2c66affSColin Finck } RX_SCAVENGER_ENTRY, *PRX_SCAVENGER_ENTRY;
17*c2c66affSColin Finck 
18*c2c66affSColin Finck #define RxInitializeScavengerEntry(ScavengerEntry) \
19*c2c66affSColin Finck     (ScavengerEntry)->State  = 0;                  \
20*c2c66affSColin Finck     (ScavengerEntry)->Flags  = 0;                  \
21*c2c66affSColin Finck     (ScavengerEntry)->Type   = 0;                  \
22*c2c66affSColin Finck     (ScavengerEntry)->Operation = 0;               \
23*c2c66affSColin Finck     InitializeListHead(&(ScavengerEntry)->List);   \
24*c2c66affSColin Finck     (ScavengerEntry)->pContinuationEntry = NULL
25*c2c66affSColin Finck 
26*c2c66affSColin Finck #define RxAcquireScavengerMutex() KeWaitForSingleObject(&RxScavengerMutex, Executive, KernelMode, FALSE, NULL)
27*c2c66affSColin Finck #define RxReleaseScavengerMutex() KeReleaseMutex(&RxScavengerMutex, FALSE)
28*c2c66affSColin Finck 
29*c2c66affSColin Finck VOID
30*c2c66affSColin Finck RxMarkFobxOnCleanup(
31*c2c66affSColin Finck     _In_ PFOBX pFobx,
32*c2c66affSColin Finck     _Out_ PBOOLEAN NeedPurge);
33*c2c66affSColin Finck 
34*c2c66affSColin Finck VOID
35*c2c66affSColin Finck RxMarkFobxOnClose(
36*c2c66affSColin Finck     _In_ PFOBX Fobx);
37*c2c66affSColin Finck 
38*c2c66affSColin Finck NTSTATUS
39*c2c66affSColin Finck RxPurgeRelatedFobxs(
40*c2c66affSColin Finck     PNET_ROOT NetRoot,
41*c2c66affSColin Finck     PRX_CONTEXT RxContext,
42*c2c66affSColin Finck     BOOLEAN AttemptFinalization,
43*c2c66affSColin Finck     PFCB PurgingFcb);
44*c2c66affSColin Finck 
45*c2c66affSColin Finck #define DONT_ATTEMPT_FINALIZE_ON_PURGE FALSE
46*c2c66affSColin Finck #define ATTEMPT_FINALIZE_ON_PURGE TRUE
47*c2c66affSColin Finck 
48*c2c66affSColin Finck typedef enum _RDBSS_SCAVENGER_STATE
49*c2c66affSColin Finck {
50*c2c66affSColin Finck     RDBSS_SCAVENGER_INACTIVE,
51*c2c66affSColin Finck     RDBSS_SCAVENGER_DORMANT,
52*c2c66affSColin Finck     RDBSS_SCAVENGER_ACTIVE,
53*c2c66affSColin Finck     RDBSS_SCAVENGER_SUSPENDED
54*c2c66affSColin Finck } RDBSS_SCAVENGER_STATE, *PRDBSS_SCAVENGER_STATE;
55*c2c66affSColin Finck 
56*c2c66affSColin Finck typedef struct _RDBSS_SCAVENGER
57*c2c66affSColin Finck {
58*c2c66affSColin Finck     RDBSS_SCAVENGER_STATE State;
59*c2c66affSColin Finck     LONG MaximumNumberOfDormantFiles;
60*c2c66affSColin Finck     volatile LONG NumberOfDormantFiles;
61*c2c66affSColin Finck     LARGE_INTEGER TimeLimit;
62*c2c66affSColin Finck     ULONG SrvCallsToBeFinalized;
63*c2c66affSColin Finck     ULONG NetRootsToBeFinalized;
64*c2c66affSColin Finck     ULONG VNetRootsToBeFinalized;
65*c2c66affSColin Finck     ULONG FcbsToBeFinalized;
66*c2c66affSColin Finck     ULONG SrvOpensToBeFinalized;
67*c2c66affSColin Finck     ULONG FobxsToBeFinalized;
68*c2c66affSColin Finck     LIST_ENTRY SrvCallFinalizationList;
69*c2c66affSColin Finck     LIST_ENTRY NetRootFinalizationList;
70*c2c66affSColin Finck     LIST_ENTRY VNetRootFinalizationList;
71*c2c66affSColin Finck     LIST_ENTRY FcbFinalizationList;
72*c2c66affSColin Finck     LIST_ENTRY SrvOpenFinalizationList;
73*c2c66affSColin Finck     LIST_ENTRY FobxFinalizationList;
74*c2c66affSColin Finck     LIST_ENTRY ClosePendingFobxsList;
75*c2c66affSColin Finck     RX_WORK_ITEM WorkItem;
76*c2c66affSColin Finck     KEVENT SyncEvent;
77*c2c66affSColin Finck     KEVENT ScavengeEvent;
78*c2c66affSColin Finck     PETHREAD CurrentScavengerThread;
79*c2c66affSColin Finck     PNET_ROOT CurrentNetRootForClosePendingProcessing;
80*c2c66affSColin Finck     PFCB CurrentFcbForClosePendingProcessing;
81*c2c66affSColin Finck     KEVENT ClosePendingProcessingSyncEvent;
82*c2c66affSColin Finck } RDBSS_SCAVENGER, *PRDBSS_SCAVENGER;
83*c2c66affSColin Finck 
84*c2c66affSColin Finck #define RxInitializeRdbssScavenger(Scavenger, ScavengerTimeLimit)                                 \
85*c2c66affSColin Finck     (Scavenger)->State = RDBSS_SCAVENGER_INACTIVE;                                                \
86*c2c66affSColin Finck     (Scavenger)->SrvCallsToBeFinalized = 0;                                                       \
87*c2c66affSColin Finck     (Scavenger)->NetRootsToBeFinalized = 0;                                                       \
88*c2c66affSColin Finck     (Scavenger)->VNetRootsToBeFinalized = 0;                                                      \
89*c2c66affSColin Finck     (Scavenger)->FcbsToBeFinalized = 0;                                                           \
90*c2c66affSColin Finck     (Scavenger)->SrvOpensToBeFinalized = 0;                                                       \
91*c2c66affSColin Finck     (Scavenger)->FobxsToBeFinalized = 0;                                                          \
92*c2c66affSColin Finck     (Scavenger)->NumberOfDormantFiles = 0;                                                        \
93*c2c66affSColin Finck     (Scavenger)->MaximumNumberOfDormantFiles = 50;                                                \
94*c2c66affSColin Finck     (Scavenger)->CurrentFcbForClosePendingProcessing = NULL;                                      \
95*c2c66affSColin Finck     (Scavenger)->CurrentNetRootForClosePendingProcessing = NULL;                                  \
96*c2c66affSColin Finck     if ((ScavengerTimeLimit).QuadPart == 0)                                                       \
97*c2c66affSColin Finck     {                                                                                             \
98*c2c66affSColin Finck           (Scavenger)->TimeLimit.QuadPart = RX_SCAVENGER_FINALIZATION_TIME_INTERVAL;              \
99*c2c66affSColin Finck     }                                                                                             \
100*c2c66affSColin Finck     else                                                                                          \
101*c2c66affSColin Finck     {                                                                                             \
102*c2c66affSColin Finck           (Scavenger)->TimeLimit.QuadPart = (ScavengerTimeLimit).QuadPart;                        \
103*c2c66affSColin Finck     }                                                                                             \
104*c2c66affSColin Finck     KeInitializeEvent(&((Scavenger)->SyncEvent), NotificationEvent, FALSE);                       \
105*c2c66affSColin Finck     KeInitializeEvent(&((Scavenger)->ScavengeEvent), SynchronizationEvent, TRUE);                 \
106*c2c66affSColin Finck     KeInitializeEvent(&((Scavenger)->ClosePendingProcessingSyncEvent), NotificationEvent, FALSE); \
107*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->SrvCallFinalizationList);                                    \
108*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->NetRootFinalizationList);                                    \
109*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->VNetRootFinalizationList);                                   \
110*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->SrvOpenFinalizationList);                                    \
111*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->FcbFinalizationList);                                        \
112*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->FobxFinalizationList);                                       \
113*c2c66affSColin Finck     InitializeListHead(&(Scavenger)->ClosePendingFobxsList)
114*c2c66affSColin Finck 
115*c2c66affSColin Finck typedef struct _PURGE_SYNCHRONIZATION_CONTEXT
116*c2c66affSColin Finck {
117*c2c66affSColin Finck     LIST_ENTRY ContextsAwaitingPurgeCompletion;
118*c2c66affSColin Finck     BOOLEAN PurgeInProgress;
119*c2c66affSColin Finck } PURGE_SYNCHRONIZATION_CONTEXT, *PPURGE_SYNCHRONIZATION_CONTEXT;
120*c2c66affSColin Finck 
121*c2c66affSColin Finck VOID
122*c2c66affSColin Finck RxInitializePurgeSyncronizationContext(
123*c2c66affSColin Finck     _In_ PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext);
124*c2c66affSColin Finck 
125*c2c66affSColin Finck BOOLEAN
126*c2c66affSColin Finck RxScavengeRelatedFobxs(
127*c2c66affSColin Finck     _In_ PFCB Fcb);
128*c2c66affSColin Finck 
129*c2c66affSColin Finck VOID
130*c2c66affSColin Finck RxScavengeFobxsForNetRoot(
131*c2c66affSColin Finck     PNET_ROOT NetRoot,
132*c2c66affSColin Finck     PFCB PurgingFcb,
133*c2c66affSColin Finck     BOOLEAN SynchronizeWithScavenger);
134*c2c66affSColin Finck 
135*c2c66affSColin Finck VOID
136*c2c66affSColin Finck RxpMarkInstanceForScavengedFinalization(
137*c2c66affSColin Finck    PVOID Instance);
138*c2c66affSColin Finck 
139*c2c66affSColin Finck VOID
140*c2c66affSColin Finck RxpUndoScavengerFinalizationMarking(
141*c2c66affSColin Finck    _In_ PVOID Instance);
142*c2c66affSColin Finck 
143*c2c66affSColin Finck BOOLEAN
144*c2c66affSColin Finck RxScavengeVNetRoots(
145*c2c66affSColin Finck     _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject);
146*c2c66affSColin Finck 
147*c2c66affSColin Finck #if (_WIN32_WINNT >= 0x0600)
148*c2c66affSColin Finck VOID
149*c2c66affSColin Finck RxSynchronizeWithScavenger(
150*c2c66affSColin Finck     _In_ PRX_CONTEXT RxContext,
151*c2c66affSColin Finck     _In_ PFCB Fcb);
152*c2c66affSColin Finck #else
153*c2c66affSColin Finck VOID
154*c2c66affSColin Finck RxSynchronizeWithScavenger(
155*c2c66affSColin Finck     _In_ PRX_CONTEXT RxContext);
156*c2c66affSColin Finck #endif
157*c2c66affSColin Finck 
158*c2c66affSColin Finck #endif
159