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)
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
15 #include <internal/debug.h>
17 /* TYPES *********************************************************************/
22 * PURPOSE: Head of the list of waiting work items
27 * PURPOSE: Sychronize access to the access
32 * PURPOSE: Worker threads with nothing to do wait on this event
37 * PURPOSE: Thread associated with work queue
40 } WORK_QUEUE
, *PWORK_QUEUE
;
42 /* GLOBALS *******************************************************************/
45 * PURPOSE: Queue of items waiting to be processed at normal priority
47 WORK_QUEUE normal_work_queue
= {{0,}};
49 #define WAIT_INTERVAL (0)
51 /* FUNCTIONS ****************************************************************/
53 static NTSTATUS
ExWorkerThreadEntryPoint(PVOID context
)
55 * FUNCTION: Entry point for a worker thread
57 * context = Parameters
59 * NOTE: To kill a worker thread you must queue an item whose callback
60 * calls PsTerminateSystemThread
63 PWORK_QUEUE param
= (PWORK_QUEUE
)context
;
64 PWORK_QUEUE_ITEM item
;
69 current
= ExInterlockedRemoveHeadList(¶m
->Head
,¶m
->Lock
);
72 item
= CONTAINING_RECORD(current
,WORK_QUEUE_ITEM
,Entry
);
73 item
->Routine(item
->Context
);
77 KeClearEvent(¶m
->Busy
);
78 KeWaitForSingleObject((PVOID
)¶m
->Busy
,Executive
,KernelMode
,
84 static VOID
ExKillWorkerThreadCallback(PVOID Context
)
86 PsTerminateSystemThread(STATUS_SUCCESS
);
89 void ExKillWorkerThreads(void)
91 * FUNCTION: Kill all running worker threads in preparation for a shutdown
94 WORK_QUEUE_ITEM item1
;
96 ExInitializeWorkItem(&item1
,ExKillWorkerThreadCallback
,NULL
);
97 ExQueueWorkItem(&item1
,DelayedWorkQueue
);
100 void ExInitializeWorkerThreads(void)
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
,
110 VOID
ExInitializeWorkItem(PWORK_QUEUE_ITEM Item
,
111 PWORKER_THREAD_ROUTINE Routine
,
114 * FUNCTION: Initializes a work item to be processed by one of the system
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
122 ASSERT_IRQL(DISPATCH_LEVEL
);
124 Item
->Routine
=Routine
;
125 Item
->Context
=Context
;
126 Item
->Entry
.Flink
=NULL
;
127 Item
->Entry
.Blink
=NULL
;
130 VOID
ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem
,
131 WORK_QUEUE_TYPE QueueType
)
133 * FUNCTION: Inserts a work item in a queue for one of the system worker
136 * WorkItem = Item to insert
137 * QueueType = Queue to insert it in
140 assert(WorkItem
!=NULL
);
141 ASSERT_IRQL(DISPATCH_LEVEL
);
144 * Insert the item in the appropiate queue and wake up any thread
145 * waiting for something to do
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
);