mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 14:13:01 +00:00
[NTOSKRNL]
Implement PoQueueShutdownWorkItem, PoRequestShutdownEvent, PoRequestShutdownWait, PopProcessShutDownLists. One step closer to ... proper shutdown. svn path=/trunk/; revision=61041
This commit is contained in:
parent
d9d963a62f
commit
c5b45ab5bc
3 changed files with 207 additions and 34 deletions
|
@ -255,6 +255,12 @@ typedef struct _DEVICE_OBJECT_POWER_EXTENSION
|
||||||
LIST_ENTRY Volume;
|
LIST_ENTRY Volume;
|
||||||
} DEVICE_OBJECT_POWER_EXTENSION, *PDEVICE_OBJECT_POWER_EXTENSION;
|
} DEVICE_OBJECT_POWER_EXTENSION, *PDEVICE_OBJECT_POWER_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct _POP_SHUTDOWN_WAIT_ENTRY
|
||||||
|
{
|
||||||
|
struct _POP_SHUTDOWN_WAIT_ENTRY *NextEntry;
|
||||||
|
PETHREAD Thread;
|
||||||
|
} POP_SHUTDOWN_WAIT_ENTRY, *PPOP_SHUTDOWN_WAIT_ENTRY;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialization routines
|
// Initialization routines
|
||||||
//
|
//
|
||||||
|
@ -270,6 +276,12 @@ PoInitializePrcb(
|
||||||
IN PKPRCB Prcb
|
IN PKPRCB Prcb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PopInitShutdownList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// I/O Routines
|
// I/O Routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -18,9 +18,130 @@
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
ULONG PopShutdownPowerOffPolicy;
|
ULONG PopShutdownPowerOffPolicy;
|
||||||
|
KEVENT PopShutdownEvent;
|
||||||
|
PPOP_SHUTDOWN_WAIT_ENTRY PopShutdownThreadList;
|
||||||
|
LIST_ENTRY PopShutdownQueue;
|
||||||
|
KGUARDED_MUTEX PopShutdownListMutex;
|
||||||
|
BOOLEAN PopShutdownListAvailable;
|
||||||
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PopInitShutdownList(VOID)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Initialize the global shutdown event */
|
||||||
|
KeInitializeEvent(&PopShutdownEvent, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
/* Initialize the shutdown lists */
|
||||||
|
PopShutdownThreadList = NULL;
|
||||||
|
InitializeListHead(&PopShutdownQueue);
|
||||||
|
|
||||||
|
/* Initialize the shutdown list lock */
|
||||||
|
KeInitializeGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* The list is available now */
|
||||||
|
PopShutdownListAvailable = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PoRequestShutdownWait(
|
||||||
|
_In_ PETHREAD Thread)
|
||||||
|
{
|
||||||
|
PPOP_SHUTDOWN_WAIT_ENTRY ShutDownWaitEntry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Allocate a new shutdown wait entry */
|
||||||
|
ShutDownWaitEntry = ExAllocatePoolWithTag(PagedPool, 8u, 'LSoP');
|
||||||
|
if (ShutDownWaitEntry == NULL)
|
||||||
|
{
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the thread and save it in the wait entry */
|
||||||
|
ObReferenceObject(Thread);
|
||||||
|
ShutDownWaitEntry->Thread = Thread;
|
||||||
|
|
||||||
|
/* Acquire the shutdown list lock */
|
||||||
|
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* Check if the list is still available */
|
||||||
|
if (PopShutdownListAvailable)
|
||||||
|
{
|
||||||
|
/* Insert the item in the list */
|
||||||
|
ShutDownWaitEntry->NextEntry = PopShutdownThreadList;
|
||||||
|
PopShutdownThreadList = ShutDownWaitEntry;
|
||||||
|
|
||||||
|
/* We are successful */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We cannot proceed, cleanup and return failure */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
ExFreePoolWithTag(ShutDownWaitEntry, 0);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the list lock */
|
||||||
|
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* Return the status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PopProcessShutDownLists(VOID)
|
||||||
|
{
|
||||||
|
PPOP_SHUTDOWN_WAIT_ENTRY ShutDownWaitEntry;
|
||||||
|
PWORK_QUEUE_ITEM WorkItem;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* First signal the shutdown event */
|
||||||
|
KeSetEvent(&PopShutdownEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
|
/* Acquire the shutdown list lock */
|
||||||
|
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* Block any further attempts to register a shutdown event */
|
||||||
|
PopShutdownListAvailable = FALSE;
|
||||||
|
|
||||||
|
/* Release the list lock, since we are exclusively using the lists now */
|
||||||
|
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* Process the shutdown queue */
|
||||||
|
while (!IsListEmpty(&PopShutdownQueue))
|
||||||
|
{
|
||||||
|
/* Get the head entry */
|
||||||
|
ListEntry = RemoveHeadList(&PopShutdownQueue);
|
||||||
|
WorkItem = CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List);
|
||||||
|
|
||||||
|
/* Call the shutdown worker routine */
|
||||||
|
WorkItem->WorkerRoutine(WorkItem->Parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now process the shutdown thread list */
|
||||||
|
while (PopShutdownThreadList != NULL)
|
||||||
|
{
|
||||||
|
/* Get the top entry and remove it from the list */
|
||||||
|
ShutDownWaitEntry = PopShutdownThreadList;
|
||||||
|
PopShutdownThreadList = PopShutdownThreadList->NextEntry;
|
||||||
|
|
||||||
|
/* Wait for the thread to finish and dereference it */
|
||||||
|
KeWaitForSingleObject(ShutDownWaitEntry->Thread, 0, 0, 0, 0);
|
||||||
|
ObfDereferenceObject(ShutDownWaitEntry->Thread);
|
||||||
|
|
||||||
|
/* Finally free the entry */
|
||||||
|
ExFreePoolWithTag(ShutDownWaitEntry, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PopShutdownHandler(VOID)
|
PopShutdownHandler(VOID)
|
||||||
|
@ -124,6 +245,9 @@ PopGracefulShutdown(IN PVOID Context)
|
||||||
{
|
{
|
||||||
PEPROCESS Process = NULL;
|
PEPROCESS Process = NULL;
|
||||||
|
|
||||||
|
/* Process the registered waits and work items */
|
||||||
|
PopProcessShutDownLists();
|
||||||
|
|
||||||
/* Loop every process */
|
/* Loop every process */
|
||||||
Process = PsGetNextProcess(Process);
|
Process = PsGetNextProcess(Process);
|
||||||
while (Process)
|
while (Process)
|
||||||
|
@ -220,3 +344,60 @@ PopReadShutdownPolicy(VOID)
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PoQueueShutdownWorkItem(
|
||||||
|
_In_ PWORK_QUEUE_ITEM WorkItem)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Acquire the shutdown list lock */
|
||||||
|
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
/* Check if the list is (already/still) available */
|
||||||
|
if (PopShutdownListAvailable)
|
||||||
|
{
|
||||||
|
/* Insert the item into the list */
|
||||||
|
InsertTailList(&PopShutdownQueue, &WorkItem->List);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We are already in shutdown */
|
||||||
|
Status = STATUS_SYSTEM_SHUTDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the list lock */
|
||||||
|
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PoRequestShutdownEvent(OUT PVOID *Event)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Initialize to NULL */
|
||||||
|
if (Event) *Event = NULL;
|
||||||
|
|
||||||
|
/* Request a shutdown wait */
|
||||||
|
Status = PoRequestShutdownWait(PsGetCurrentThread());
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the global shutdown event */
|
||||||
|
if (Event) *Event = &PopShutdownEvent;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,10 @@ PoInitSystem(IN ULONG BootPhase)
|
||||||
|
|
||||||
/* Initialize support for dope */
|
/* Initialize support for dope */
|
||||||
KeInitializeSpinLock(&PopDopeGlobalLock);
|
KeInitializeSpinLock(&PopDopeGlobalLock);
|
||||||
|
|
||||||
|
/* Initialize support for shutdown waits and work-items */
|
||||||
|
PopInitShutdownList();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,17 +449,6 @@ PoShutdownBugCheck(IN BOOLEAN LogError,
|
||||||
BugCheckParameter4);
|
BugCheckParameter4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
PoRequestShutdownEvent(OUT PVOID *Event)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -637,19 +630,6 @@ PoUnregisterSystemState(IN PVOID StateHandle)
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
PoQueueShutdownWorkItem(IN PWORK_QUEUE_ITEM WorkItem)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue