Fixed header inclusion order.
[reactos.git] / reactos / ntoskrnl / ex / work.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: mkernel/kernel/work.c
5 * PURPOSE: Manage system work queues
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * REVISION HISTORY:
8 * 29/06/98: Created
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14
15 #include <internal/debug.h>
16
17 /* TYPES *********************************************************************/
18
19 typedef struct
20 {
21 /*
22 * PURPOSE: Head of the list of waiting work items
23 */
24 LIST_ENTRY Head;
25
26 /*
27 * PURPOSE: Sychronize access to the access
28 */
29 KSPIN_LOCK Lock;
30
31 /*
32 * PURPOSE: Worker threads with nothing to do wait on this event
33 */
34 KEVENT Busy;
35
36 /*
37 * PURPOSE: Thread associated with work queue
38 */
39 HANDLE Thread;
40 } WORK_QUEUE, *PWORK_QUEUE;
41
42 /* GLOBALS *******************************************************************/
43
44 /*
45 * PURPOSE: Queue of items waiting to be processed at normal priority
46 */
47 WORK_QUEUE normal_work_queue = {{0,}};
48
49 #define WAIT_INTERVAL (0)
50
51 /* FUNCTIONS ****************************************************************/
52
53 static NTSTATUS ExWorkerThreadEntryPoint(PVOID context)
54 /*
55 * FUNCTION: Entry point for a worker thread
56 * ARGUMENTS:
57 * context = Parameters
58 * RETURNS: Status
59 * NOTE: To kill a worker thread you must queue an item whose callback
60 * calls PsTerminateSystemThread
61 */
62 {
63 PWORK_QUEUE param = (PWORK_QUEUE)context;
64 PWORK_QUEUE_ITEM item;
65 PLIST_ENTRY current;
66
67 while (1)
68 {
69 current = ExInterlockedRemoveHeadList(&param->Head,&param->Lock);
70 if (current!=NULL)
71 {
72 item = CONTAINING_RECORD(current,WORK_QUEUE_ITEM,Entry);
73 item->Routine(item->Context);
74 }
75 else
76 {
77 KeClearEvent(&param->Busy);
78 KeWaitForSingleObject((PVOID)&param->Busy,Executive,KernelMode,
79 FALSE,WAIT_INTERVAL);
80 }
81 };
82 }
83
84 static VOID ExKillWorkerThreadCallback(PVOID Context)
85 {
86 PsTerminateSystemThread(STATUS_SUCCESS);
87 }
88
89 void ExKillWorkerThreads(void)
90 /*
91 * FUNCTION: Kill all running worker threads in preparation for a shutdown
92 */
93 {
94 WORK_QUEUE_ITEM item1;
95
96 ExInitializeWorkItem(&item1,ExKillWorkerThreadCallback,NULL);
97 ExQueueWorkItem(&item1,DelayedWorkQueue);
98 }
99
100 void ExInitializeWorkerThreads(void)
101 {
102 InitializeListHead(&normal_work_queue.Head);
103 KeInitializeSpinLock(&normal_work_queue.Lock);
104 KeInitializeEvent(&normal_work_queue.Busy,NotificationEvent,FALSE);
105 PsCreateSystemThread(&normal_work_queue.Thread,THREAD_ALL_ACCESS,
106 NULL,NULL,NULL,ExWorkerThreadEntryPoint,
107 &normal_work_queue);
108 }
109
110 VOID ExInitializeWorkItem(PWORK_QUEUE_ITEM Item,
111 PWORKER_THREAD_ROUTINE Routine,
112 PVOID Context)
113 /*
114 * FUNCTION: Initializes a work item to be processed by one of the system
115 * worker threads
116 * ARGUMENTS:
117 * Item = Pointer to the item to be initialized
118 * Routine = Routine to be called by the worker thread
119 * Context = Parameter to be passed to the callback
120 */
121 {
122 ASSERT_IRQL(DISPATCH_LEVEL);
123
124 Item->Routine=Routine;
125 Item->Context=Context;
126 Item->Entry.Flink=NULL;
127 Item->Entry.Blink=NULL;
128 }
129
130 VOID ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem,
131 WORK_QUEUE_TYPE QueueType)
132 /*
133 * FUNCTION: Inserts a work item in a queue for one of the system worker
134 * threads to process
135 * ARGUMENTS:
136 * WorkItem = Item to insert
137 * QueueType = Queue to insert it in
138 */
139 {
140 assert(WorkItem!=NULL);
141 ASSERT_IRQL(DISPATCH_LEVEL);
142
143 /*
144 * Insert the item in the appropiate queue and wake up any thread
145 * waiting for something to do
146 */
147 switch(QueueType)
148 {
149 case DelayedWorkQueue:
150 ExInterlockedInsertTailList(&normal_work_queue.Head,&(WorkItem->Entry),
151 &normal_work_queue.Lock);
152 KeSetEvent(&normal_work_queue.Busy,IO_NO_INCREMENT,FALSE);
153 break;
154 }
155 }