[NTOSKRNL_VISTA] Implement IoGetIrpExtraCreateParameter
[reactos.git] / sdk / lib / drivers / chew / workqueue.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/drivers/chew/workqueue.c
5 * PURPOSE: Common Highlevel Executive Worker
6 *
7 * PROGRAMMERS: arty (ayerkes@speakeasy.net)
8 */
9
10 #include <ntddk.h>
11 #include <chew/chew.h>
12
13 #define NDEBUG
14 //#include <debug.h>
15
16 #define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))
17 #define CHEW_TAG FOURCC('C','H','E','W')
18
19 PDEVICE_OBJECT WorkQueueDevice;
20 LIST_ENTRY WorkQueue;
21 KSPIN_LOCK WorkQueueLock;
22 KEVENT WorkQueueClear;
23
24 typedef struct _WORK_ITEM
25 {
26 LIST_ENTRY Entry;
27 PIO_WORKITEM WorkItem;
28 VOID (*Worker)(PVOID WorkerContext);
29 PVOID WorkerContext;
30 } WORK_ITEM, *PWORK_ITEM;
31
32 VOID ChewInit(PDEVICE_OBJECT DeviceObject)
33 {
34 WorkQueueDevice = DeviceObject;
35 InitializeListHead(&WorkQueue);
36 KeInitializeSpinLock(&WorkQueueLock);
37 KeInitializeEvent(&WorkQueueClear, NotificationEvent, TRUE);
38 }
39
40 VOID ChewShutdown(VOID)
41 {
42 KeWaitForSingleObject(&WorkQueueClear, Executive, KernelMode, FALSE, NULL);
43 }
44
45 VOID NTAPI ChewWorkItem(PDEVICE_OBJECT DeviceObject, PVOID ChewItem)
46 {
47 PWORK_ITEM WorkItem = ChewItem;
48 KIRQL OldIrql;
49
50 WorkItem->Worker(WorkItem->WorkerContext);
51
52 IoFreeWorkItem(WorkItem->WorkItem);
53
54 KeAcquireSpinLock(&WorkQueueLock, &OldIrql);
55 RemoveEntryList(&WorkItem->Entry);
56
57 if (IsListEmpty(&WorkQueue))
58 KeSetEvent(&WorkQueueClear, 0, FALSE);
59
60 KeReleaseSpinLock(&WorkQueueLock, OldIrql);
61
62 ExFreePoolWithTag(WorkItem, CHEW_TAG);
63 }
64
65 BOOLEAN ChewCreate(VOID (*Worker)(PVOID), PVOID WorkerContext)
66 {
67 PWORK_ITEM Item;
68 Item = ExAllocatePoolWithTag(NonPagedPool,
69 sizeof(WORK_ITEM),
70 CHEW_TAG);
71
72 if (Item)
73 {
74 Item->WorkItem = IoAllocateWorkItem(WorkQueueDevice);
75 if (!Item->WorkItem)
76 {
77 ExFreePool(Item);
78 return FALSE;
79 }
80
81 Item->Worker = Worker;
82 Item->WorkerContext = WorkerContext;
83 ExInterlockedInsertTailList(&WorkQueue, &Item->Entry, &WorkQueueLock);
84 KeClearEvent(&WorkQueueClear);
85 IoQueueWorkItem(Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item);
86
87 return TRUE;
88 }
89 else
90 {
91 return FALSE;
92 }
93 }