1 /* ===============================================================
2 Worker Management Functions
16 PWORK_QUEUE_ITEM WorkItem
;
18 ULONG DeleteInProgress
;
28 IN WORK_QUEUE_TYPE WorkQueueType
,
29 OUT PKSWORKER
* Worker
)
34 if (WorkQueueType
!= CriticalWorkQueue
&&
35 WorkQueueType
!= DelayedWorkQueue
&&
36 WorkQueueType
!= HyperCriticalWorkQueue
)
38 return STATUS_INVALID_PARAMETER
;
41 KsWorker
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(KS_WORKER
), 0);
43 return STATUS_INSUFFICIENT_RESOURCES
;
45 KsWorker
->Type
= WorkQueueType
;
46 KsWorker
->Counter
= 0;
47 KsWorker
->WorkItemActive
= 0;
48 KsWorker
->WorkItem
= NULL
;
49 KsWorker
->DeleteInProgress
= TRUE
;
50 KeInitializeSpinLock(&KsWorker
->Lock
);
51 KeInitializeEvent(&KsWorker
->Event
, NotificationEvent
, FALSE
);
54 return STATUS_SUCCESS
;
71 KsWorker
= (KS_WORKER
*)Worker
;
73 KsWorker
->DeleteInProgress
= TRUE
;
75 if (KsWorker
->WorkItemActive
)
77 KeReleaseSpinLock(&KsWorker
->Lock
, OldIrql
);
78 KeWaitForSingleObject(&KsWorker
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
82 KeReleaseSpinLock(&KsWorker
->Lock
, OldIrql
);
85 ExFreePoolWithTag(KsWorker
, 0);
91 KSDDKAPI NTSTATUS NTAPI
92 KsRegisterCountedWorker(
93 IN WORK_QUEUE_TYPE WorkQueueType
,
94 IN PWORK_QUEUE_ITEM CountedWorkItem
,
95 OUT PKSWORKER
* Worker
)
100 Status
= KsRegisterWorker(WorkQueueType
, Worker
);
102 if (NT_SUCCESS(Status
))
104 KsWorker
= (KS_WORKER
*)Worker
;
105 KsWorker
->WorkItem
= CountedWorkItem
;
117 KsDecrementCountedWorker(
120 KS_WORKER
* KsWorker
;
124 return STATUS_INVALID_PARAMETER
;
126 KsWorker
= (KS_WORKER
*)Worker
;
127 Counter
= InterlockedDecrement(&KsWorker
->Counter
);
129 if (KsWorker
->DeleteInProgress
)
131 /* signal that we are done */
132 KeSetEvent(&KsWorker
->Event
, 0, 0);
144 KsIncrementCountedWorker(
147 KS_WORKER
* KsWorker
;
151 return STATUS_INVALID_PARAMETER
;
153 KsWorker
= (KS_WORKER
*)Worker
;
155 Counter
= InterlockedIncrement(&KsWorker
->Counter
);
158 KsQueueWorkItem(Worker
, KsWorker
->WorkItem
);
171 IN PWORK_QUEUE_ITEM WorkItem
)
173 KS_WORKER
* KsWorker
;
175 NTSTATUS Status
= STATUS_SUCCESS
;
177 if (!Worker
|| !WorkItem
)
178 return STATUS_INVALID_PARAMETER
;
180 KsWorker
= (KS_WORKER
*)Worker
;
181 KeAcquireSpinLock(&KsWorker
->Lock
, &OldIrql
);
183 if (!KsWorker
->DeleteInProgress
)
185 ExQueueWorkItem(WorkItem
, KsWorker
->Type
);
186 Status
= STATUS_UNSUCCESSFUL
;
189 KeReleaseSpinLock(&KsWorker
->Lock
, OldIrql
);