ReactOS  0.4.13-dev-259-g5ca9c9c
worker.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for worker.c:

Go to the source code of this file.

Classes

struct  KSIWORKER
 

Macros

#define NDEBUG
 

Typedefs

typedef struct KSIWORKERPKSIWORKER
 

Functions

VOID NTAPI WorkItemRoutine (IN PVOID Context)
 
KSDDKAPI NTSTATUS NTAPI KsRegisterWorker (IN WORK_QUEUE_TYPE WorkQueueType, OUT PKSWORKER *Worker)
 
KSDDKAPI VOID NTAPI KsUnregisterWorker (IN PKSWORKER Worker)
 
KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker (IN WORK_QUEUE_TYPE WorkQueueType, IN PWORK_QUEUE_ITEM CountedWorkItem, OUT PKSWORKER *Worker)
 
KSDDKAPI ULONG NTAPI KsDecrementCountedWorker (IN PKSWORKER Worker)
 
KSDDKAPI ULONG NTAPI KsIncrementCountedWorker (IN PKSWORKER Worker)
 
KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem (IN PKSWORKER Worker, IN PWORK_QUEUE_ITEM WorkItem)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file worker.c.

Typedef Documentation

◆ PKSIWORKER

Function Documentation

◆ KsDecrementCountedWorker()

KSDDKAPI ULONG NTAPI KsDecrementCountedWorker ( IN PKSWORKER  Worker)

Definition at line 198 of file worker.c.

200 {
201  PKSIWORKER KsWorker;
202  LONG Counter;
203 
204  /* did the caller pass a work ctx */
205  if (!Worker)
207 
208  /* get ks worker implementation */
209  KsWorker = (PKSIWORKER)Worker;
210  /* decrement counter */
211  Counter = InterlockedDecrement(&KsWorker->Counter);
212  /* return result */
213  return Counter;
214 }
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct KSIWORKER * PKSIWORKER
LONG Counter
Definition: worker.c:25
long LONG
Definition: pedump.c:60
#define InterlockedDecrement
Definition: armddk.h:52
static LARGE_INTEGER Counter
Definition: clock.c:43

Referenced by CaptureAvoidPipeStarvationWorker(), CaptureGateOnWorkItem(), and IKsPin_PrepareStreamHeader().

◆ KsIncrementCountedWorker()

KSDDKAPI ULONG NTAPI KsIncrementCountedWorker ( IN PKSWORKER  Worker)

Definition at line 222 of file worker.c.

224 {
225  PKSIWORKER KsWorker;
226  LONG Counter;
227 
228  /* did the caller pass a work ctx */
229  if (!Worker)
231 
232  /* get ks worker implementation */
233  KsWorker = (PKSIWORKER)Worker;
234  /* increment counter */
235  Counter = InterlockedIncrement(&KsWorker->Counter);
236  if (Counter == 1)
237  {
238  /* this is the first work item in list, so queue a real work item */
239  KsQueueWorkItem(Worker, KsWorker->CountedWorkItem);
240  }
241 
242  /* return current counter */
243  return Counter;
244 }
KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem(IN PKSWORKER Worker, IN PWORK_QUEUE_ITEM WorkItem)
Definition: worker.c:252
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct KSIWORKER * PKSIWORKER
LONG Counter
Definition: worker.c:25
long LONG
Definition: pedump.c:60
#define InterlockedIncrement
Definition: armddk.h:53
static LARGE_INTEGER Counter
Definition: clock.c:43
PWORK_QUEUE_ITEM CountedWorkItem
Definition: worker.c:29

Referenced by IKsPin_DispatchKsStream(), and UsbAudioCaptureComplete().

◆ KsQueueWorkItem()

KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem ( IN PKSWORKER  Worker,
IN PWORK_QUEUE_ITEM  WorkItem 
)

Definition at line 252 of file worker.c.

255 {
256  PKSIWORKER KsWorker;
257  KIRQL OldIrql;
258 
259  /* check for all parameters */
260  if (!Worker || !WorkItem)
262 
263  /* get ks worker implementation */
264  KsWorker = (PKSIWORKER)Worker;
265  /* lock the work queue */
266  KeAcquireSpinLock(&KsWorker->Lock, &OldIrql);
267  /* insert work item to list */
268  InsertTailList(&KsWorker->QueuedWorkItems, &WorkItem->List);
269  /* increment active count */
271  /* is this the first work item */
272  if (KsWorker->QueuedWorkItemCount == 1)
273  {
274  /* clear event */
275  KeClearEvent(&KsWorker->Event);
276  /* it is, queue it */
277  ExQueueWorkItem(&KsWorker->WorkItem, KsWorker->Type);
278  }
279  /* release lock */
280  KeReleaseSpinLock(&KsWorker->Lock, OldIrql);
281 
282  return STATUS_SUCCESS;
283 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
KEVENT Event
Definition: worker.c:22
#define InsertTailList(ListHead, Entry)
struct KSIWORKER * PKSIWORKER
WORK_QUEUE_ITEM WorkItem
Definition: worker.c:20
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK Lock
Definition: worker.c:23
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define InterlockedIncrement
Definition: armddk.h:53
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
return STATUS_SUCCESS
Definition: btrfs.c:2745
WORK_QUEUE_TYPE Type
Definition: worker.c:24
LIST_ENTRY QueuedWorkItems
Definition: worker.c:27
LONG QueuedWorkItemCount
Definition: worker.c:26

Referenced by IKsProcessingObject_fnProcess(), KsGenerateEvent(), and KsIncrementCountedWorker().

◆ KsRegisterCountedWorker()

KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker ( IN WORK_QUEUE_TYPE  WorkQueueType,
IN PWORK_QUEUE_ITEM  CountedWorkItem,
OUT PKSWORKER *  Worker 
)

Definition at line 166 of file worker.c.

170 {
172  PKSIWORKER KsWorker;
173 
174  /* check for counted work item parameter */
175  if (!CountedWorkItem)
177 
178  /* create the work ctx */
179  Status = KsRegisterWorker(WorkQueueType, Worker);
180  /* check for success */
181  if (NT_SUCCESS(Status))
182  {
183  /* get ks worker implementation */
184  KsWorker = *(PKSIWORKER*)Worker;
185  /* store counted work item */
186  KsWorker->CountedWorkItem = CountedWorkItem;
187  }
188 
189  return Status;
190 }
KSDDKAPI NTSTATUS NTAPI KsRegisterWorker(IN WORK_QUEUE_TYPE WorkQueueType, OUT PKSWORKER *Worker)
Definition: worker.c:88
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
PWORK_QUEUE_ITEM CountedWorkItem
Definition: worker.c:29

Referenced by InitCapturePin(), KspCreateFilter(), and KspCreatePin().

◆ KsRegisterWorker()

KSDDKAPI NTSTATUS NTAPI KsRegisterWorker ( IN WORK_QUEUE_TYPE  WorkQueueType,
OUT PKSWORKER *  Worker 
)

Definition at line 88 of file worker.c.

91 {
92  PKSIWORKER KsWorker;
93 
94 
95  if (WorkQueueType != CriticalWorkQueue &&
96  WorkQueueType != DelayedWorkQueue &&
97  WorkQueueType != HyperCriticalWorkQueue)
98  {
100  }
101 
102  /* allocate worker context */
103  KsWorker = AllocateItem(NonPagedPool, sizeof(KSIWORKER));
104  if (!KsWorker)
106 
107  /* initialize the work ctx */
108  ExInitializeWorkItem(&KsWorker->WorkItem, WorkItemRoutine, (PVOID)KsWorker);
109  /* setup type */
110  KsWorker->Type = WorkQueueType;
111  /* Initialize work item queue */
113  /* initialize work item lock */
114  KeInitializeSpinLock(&KsWorker->Lock);
115  /* initialize event */
117 
118  *Worker = KsWorker;
119  return STATUS_SUCCESS;
120 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
KEVENT Event
Definition: worker.c:22
VOID NTAPI WorkItemRoutine(IN PVOID Context)
Definition: worker.c:34
WORK_QUEUE_ITEM WorkItem
Definition: worker.c:20
KSPIN_LOCK Lock
Definition: worker.c:23
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
return STATUS_SUCCESS
Definition: btrfs.c:2745
WORK_QUEUE_TYPE Type
Definition: worker.c:24
LIST_ENTRY QueuedWorkItems
Definition: worker.c:27

Referenced by KsRegisterCountedWorker().

◆ KsUnregisterWorker()

KSDDKAPI VOID NTAPI KsUnregisterWorker ( IN PKSWORKER  Worker)

Definition at line 128 of file worker.c.

130 {
131  PKSIWORKER KsWorker;
132  KIRQL OldIrql;
133 
134  if (!Worker)
135  return;
136 
137  /* get ks worker implementation */
138  KsWorker = (PKSIWORKER)Worker;
139  /* acquire spinlock */
140  KeAcquireSpinLock(&KsWorker->Lock, &OldIrql);
141  /* fake status running to avoid work items to be queued by the counted worker */
142  KsWorker->Counter = 1;
143  /* is there currently a work item active */
144  if (KsWorker->QueuedWorkItemCount)
145  {
146  /* release the lock */
147  KeReleaseSpinLock(&KsWorker->Lock, OldIrql);
148  /* wait for the worker routine to finish */
150  }
151  else
152  {
153  /* no work item active, just release the lock */
154  KeReleaseSpinLock(&KsWorker->Lock, OldIrql);
155  }
156  /* free worker context */
157  FreeItem(KsWorker);
158 }
KEVENT Event
Definition: worker.c:22
struct KSIWORKER * PKSIWORKER
LONG Counter
Definition: worker.c:25
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
KSPIN_LOCK Lock
Definition: worker.c:23
smooth NULL
Definition: ftsmooth.c:416
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
LONG QueuedWorkItemCount
Definition: worker.c:26

Referenced by InitCapturePin(), and KspCreateFilter().

◆ WorkItemRoutine()

VOID NTAPI WorkItemRoutine ( IN PVOID  Context)

Definition at line 34 of file worker.c.

36 {
37  PKSIWORKER KsWorker;
38  KIRQL OldLevel;
39  PWORK_QUEUE_ITEM WorkItem;
41 
42 
43  /* get ks worker implementation */
44  KsWorker = (PKSIWORKER)Context;
45 
46  /* acquire back the lock */
47  KeAcquireSpinLock(&KsWorker->Lock, &OldLevel);
48 
49  do
50  {
51  /* sanity check */
52  ASSERT(!IsListEmpty(&KsWorker->QueuedWorkItems));
53 
54  /* remove first entry */
55  Entry = RemoveHeadList(&KsWorker->QueuedWorkItems);
56  /* get offset to work item */
58 
59  /* release lock as the callback might call one KsWorker functions */
60  KeReleaseSpinLock(&KsWorker->Lock, OldLevel);
61 
62  /* now dispatch the work */
63  WorkItem->WorkerRoutine(WorkItem->Parameter);
64 
65  /* acquire back the lock */
66  KeAcquireSpinLock(&KsWorker->Lock, &OldLevel);
67 
68  /* decrement queued work item count */
70 
71  }while(KsWorker->QueuedWorkItemCount);
72 
73  /* release the lock */
74  KeReleaseSpinLock(&KsWorker->Lock, OldLevel);
75 
76  /* signal completion event */
77  KeSetEvent(&KsWorker->Event, IO_NO_INCREMENT, FALSE);
78 
79 }
struct _Entry Entry
Definition: kefuncs.h:640
KEVENT Event
Definition: worker.c:22
struct KSIWORKER * PKSIWORKER
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
volatile PVOID Parameter
Definition: extypes.h:205
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK Lock
Definition: worker.c:23
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY List
Definition: psmgr.c:57
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InterlockedDecrement
Definition: armddk.h:52
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: extypes.h:204
Definition: typedefs.h:117
struct _WORK_QUEUE_ITEM * PWORK_QUEUE_ITEM
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IO_NO_INCREMENT
Definition: iotypes.h:565
LIST_ENTRY QueuedWorkItems
Definition: worker.c:27
LONG QueuedWorkItemCount
Definition: worker.c:26
base of all file and directory entries
Definition: entries.h:82

Referenced by KsRegisterWorker().