Author: tkreuzer
Date: Mon Nov 18 17:47:37 2013
New Revision: 61041

URL: http://svn.reactos.org/svn/reactos?rev=61041&view=rev
Log:
[NTOSKRNL]
Implement PoQueueShutdownWorkItem, PoRequestShutdownEvent, 
PoRequestShutdownWait, PopProcessShutDownLists. One step closer to ... proper 
shutdown.

Modified:
    trunk/reactos/ntoskrnl/include/internal/po.h
    trunk/reactos/ntoskrnl/po/poshtdwn.c
    trunk/reactos/ntoskrnl/po/power.c

Modified: trunk/reactos/ntoskrnl/include/internal/po.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/po.h?rev=61041&r1=61040&r2=61041&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/po.h        [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/po.h        [iso-8859-1] Mon Nov 18 
17:47:37 2013
@@ -240,7 +240,7 @@
     ULONG D0Count;
     LIST_ENTRY NotifyList;
 } POWER_CHANNEL_SUMMARY, *PPOWER_CHANNEL_SUMMARY;
-    
+
 typedef struct  _DEVICE_OBJECT_POWER_EXTENSION
 {
     ULONG IdleCount;
@@ -255,6 +255,12 @@
     LIST_ENTRY Volume;
 } 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
 //
@@ -268,6 +274,12 @@
 NTAPI
 PoInitializePrcb(
     IN PKPRCB Prcb
+);
+
+VOID
+NTAPI
+PopInitShutdownList(
+    VOID
 );
 
 //

Modified: trunk/reactos/ntoskrnl/po/poshtdwn.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/poshtdwn.c?rev=61041&r1=61040&r2=61041&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/po/poshtdwn.c        [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/po/poshtdwn.c        [iso-8859-1] Mon Nov 18 
17:47:37 2013
@@ -18,8 +18,129 @@
 /* GLOBALS *******************************************************************/
 
 ULONG PopShutdownPowerOffPolicy;
+KEVENT PopShutdownEvent;
+PPOP_SHUTDOWN_WAIT_ENTRY PopShutdownThreadList;
+LIST_ENTRY PopShutdownQueue;
+KGUARDED_MUTEX PopShutdownListMutex;
+BOOLEAN PopShutdownListAvailable;
+
 
 /* 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
 NTAPI
@@ -27,7 +148,7 @@
 {
     PUCHAR Logo1, Logo2;
     ULONG i;
-    
+
     /* Stop all interrupts */
     KeRaiseIrqlToDpcLevel();
     _disable();
@@ -72,7 +193,7 @@
     /* Unload symbols */
     DPRINT1("It's the final countdown...%lx\n", SystemAction);
     DbgUnLoadImageSymbols(NULL, (PVOID)-1, 0);
-    
+
     /* Run the thread on the boot processor */
     KeSetSystemAffinityThread(1);
 
@@ -101,7 +222,7 @@
 
             /* Call shutdown handler */
             //PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL);
-            
+
             /* ReactOS Hack */
             PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
             PopShutdownHandler();
@@ -123,6 +244,9 @@
 PopGracefulShutdown(IN PVOID Context)
 {
     PEPROCESS Process = NULL;
+
+    /* Process the registered waits and work items */
+    PopProcessShutDownLists();
 
     /* Loop every process */
     Process = PsGetNextProcess(Process);
@@ -144,13 +268,13 @@
     HalEndOfBoot();
 
     /* In this step, the I/O manager does first-chance shutdown notification */
-    DPRINT1("I/O manager shutting down in phase 0\n");    
+    DPRINT1("I/O manager shutting down in phase 0\n");
     IoShutdownSystem(0);
-    
+
     /* In this step, all workers are killed and hives are flushed */
     DPRINT1("Configuration Manager shutting down\n");
     CmShutdownSystem();
-    
+
     /* Note that modified pages should be written here (MiShutdownSystem) */
 #ifdef NEWCC
        /* Flush all user files before we start shutting down IO */
@@ -159,7 +283,7 @@
 #endif
 
     /* In this step, the I/O manager does last-chance shutdown notification */
-    DPRINT1("I/O manager shutting down in phase 1\n"); 
+    DPRINT1("I/O manager shutting down in phase 1\n");
     IoShutdownSystem(1);
     CcWaitForCurrentLazyWriterActivity();
 
@@ -168,7 +292,7 @@
     /* In this step, the HAL disables any wake timers */
     DPRINT1("Disabling wake timers\n");
     HalSetWakeEnable(FALSE);
-    
+
     /* And finally the power request is sent */
     DPRINT1("Taking the system down\n");
     PopShutdownSystem(PopAction.Action);
@@ -185,7 +309,7 @@
     ULONG Length;
     UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
     PKEY_VALUE_PARTIAL_INFORMATION Info = (PVOID)Buffer;
-    
+
     /* Setup object attributes */
     RtlInitUnicodeString(&KeyString,
                          
L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT");
@@ -220,3 +344,60 @@
 
 /* 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;
+}
+

Modified: trunk/reactos/ntoskrnl/po/power.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/power.c?rev=61041&r1=61040&r2=61041&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/po/power.c   [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/po/power.c   [iso-8859-1] Mon Nov 18 17:47:37 2013
@@ -344,6 +344,10 @@
     
     /* Initialize support for dope */
     KeInitializeSpinLock(&PopDopeGlobalLock);
+
+    /* Initialize support for shutdown waits and work-items */
+    PopInitShutdownList();
+
     return TRUE;
 }
 
@@ -443,17 +447,6 @@
                  BugCheckParameter2,
                  BugCheckParameter3,
                  BugCheckParameter4);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-PoRequestShutdownEvent(OUT PVOID *Event)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
 }
 
 /*
@@ -635,19 +628,6 @@
 PoUnregisterSystemState(IN PVOID StateHandle)
 {
     UNIMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-PoQueueShutdownWorkItem(IN PWORK_QUEUE_ITEM WorkItem)
-{
-    PAGED_CODE();
-
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
 }
 
 /*


Reply via email to