[SCHEDSVC]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 15 Apr 2017 10:33:29 +0000 (10:33 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 15 Apr 2017 10:33:29 +0000 (10:33 +0000)
Insert a job into the start list when it is loaded or added. Remove it from the start list when it gets deleted. The start list is sorted by start time.

svn path=/trunk/; revision=74317

reactos/base/services/schedsvc/job.c
reactos/base/services/schedsvc/precomp.h
reactos/base/services/schedsvc/rpcserver.c

index 8e7a90c..89bd28d 100644 (file)
@@ -276,19 +276,25 @@ LoadJobs(VOID)
                 pJob->JobId = dwNextJobId++;
                 dwJobCount++;
 
+                // Cancel the start timer
+
                 /* Append the new job to the job list */
                 InsertTailList(&JobListHead, &pJob->JobEntry);
 
-                /* Release the job list lock */
-                RtlReleaseResource(&JobListLock);
-
                 /* Calculate the next start time */
                 CalculateNextStartTime(pJob);
 
-                // Insert job into the start list
+                /* Insert the job into the start list */
+                InsertJobIntoStartList(&StartListHead, pJob);
+#if 0
+                DumpStartList(&StartListHead);
+#endif
 
                 // Update the start timer
 
+                /* Release the job list lock */
+                RtlReleaseResource(&JobListLock);
+
                 pJob = NULL;
             }
         }
@@ -330,8 +336,11 @@ VOID
 CalculateNextStartTime(PJOB pJob)
 {
     SYSTEMTIME StartTime;
+    FILETIME FileTime;
     DWORD_PTR Now;
 
+    TRACE("CalculateNextStartTime(%p)\n", pJob);
+
     GetLocalTime(&StartTime);
 
     Now = (DWORD_PTR)StartTime.wHour * 3600000 +
@@ -365,8 +374,82 @@ CalculateNextStartTime(PJOB pJob)
         }
     }
 
-    ERR("Next start: %02hu:%02hu %02hu.%02hu.%hu\n", StartTime.wHour,
-        StartTime.wMinute, StartTime.wDay, StartTime.wMonth, StartTime.wYear);
+    TRACE("Next start: %02hu:%02hu %02hu.%02hu.%hu\n", StartTime.wHour,
+          StartTime.wMinute, StartTime.wDay, StartTime.wMonth, StartTime.wYear);
+
+    SystemTimeToFileTime(&StartTime, &FileTime);
+    pJob->StartTime.u.LowPart = FileTime.dwLowDateTime;
+    pJob->StartTime.u.HighPart = FileTime.dwHighDateTime;
+}
+
+
+VOID
+InsertJobIntoStartList(
+    _In_ PLIST_ENTRY StartListHead,
+    _In_ PJOB pJob)
+{
+    PLIST_ENTRY CurrentEntry, PreviousEntry;
+    PJOB CurrentJob;
+
+    if (IsListEmpty(StartListHead))
+    {
+         InsertHeadList(StartListHead, &pJob->StartEntry);
+         return;
+    }
+
+    CurrentEntry = StartListHead->Flink;
+    while (CurrentEntry != StartListHead)
+    {
+        CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
+
+        if ((CurrentEntry == StartListHead->Flink) &&
+            (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart))
+        {
+            /* Insert before the first entry */
+            InsertHeadList(StartListHead, &pJob->StartEntry);
+            return;
+        }
+
+        if (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart)
+        {
+            /* Insert between the previous and the current entry */
+            PreviousEntry = CurrentEntry->Blink;
+            pJob->StartEntry.Blink = PreviousEntry;
+            pJob->StartEntry.Flink = CurrentEntry;
+            PreviousEntry->Flink = &pJob->StartEntry;
+            CurrentEntry->Blink = &pJob->StartEntry;
+            return;
+        }
+
+        if ((CurrentEntry->Flink == StartListHead) &&
+            (pJob->StartTime.QuadPart >= CurrentJob->StartTime.QuadPart))
+        {
+            /* Insert after the last entry */
+            InsertTailList(StartListHead, &pJob->StartEntry);
+            return;
+        }
+
+        CurrentEntry = CurrentEntry->Flink;
+    }
+}
+
+
+VOID
+DumpStartList(
+    _In_ PLIST_ENTRY StartListHead)
+{
+    PLIST_ENTRY CurrentEntry;
+    PJOB CurrentJob;
 
-    SystemTimeToFileTime(&StartTime, &pJob->StartTime);
+    CurrentEntry = StartListHead->Flink;
+    while (CurrentEntry != StartListHead)
+    {
+        CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
+
+        TRACE("%3lu: %016I64x\n", CurrentJob->JobId, CurrentJob->StartTime.QuadPart);
+
+        CurrentEntry = CurrentEntry->Flink;
+    }
 }
+
+/* EOF */
index 0da85a0..5d472d3 100644 (file)
@@ -4,6 +4,7 @@
 #define WIN32_NO_STATUS
 #define _INC_WINDOWS
 #define COM_NO_WINDOWS_H
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <windef.h>
@@ -28,7 +29,7 @@ typedef struct _JOB
     LIST_ENTRY JobEntry;
 
     LIST_ENTRY StartEntry;
-    FILETIME StartTime;
+    ULARGE_INTEGER StartTime;
     WCHAR Name[9];
 
     DWORD JobId;
@@ -39,7 +40,6 @@ typedef struct _JOB
     WCHAR Command[1];
 } JOB, *PJOB;
 
-#define DWORD_MAX 0xffffffffUL
 
 extern DWORD dwNextJobId;
 extern DWORD dwJobCount;
@@ -66,7 +66,17 @@ LoadJobs(VOID);
 
 VOID
 CalculateNextStartTime(
-    PJOB pJob);
+    _In_ PJOB pJob);
+
+VOID
+InsertJobIntoStartList(
+    _In_ PLIST_ENTRY StartListHead,
+    _In_ PJOB pJob);
+
+VOID
+DumpStartList(
+    _In_ PLIST_ENTRY StartListHead);
+
 
 /* rpcserver.c */
 
index e23371e..1ca2b35 100644 (file)
@@ -112,22 +112,28 @@ NetrJobAdd(
     pJob->JobId = dwNextJobId++;
     dwJobCount++;
 
+    // Cancel the start timer
+
     /* Append the new job to the job list */
     InsertTailList(&JobListHead, &pJob->JobEntry);
 
-    /* Release the job list lock */
-    RtlReleaseResource(&JobListLock);
-
     /* Save the job in the registry */
     SaveJob(pJob);
 
     /* Calculate the next start time */
     CalculateNextStartTime(pJob);
 
-    // Insert job into the start list
+    /* Insert the job into the start list */
+    InsertJobIntoStartList(&StartListHead, pJob);
+#if 0
+    DumpStartList(&StartListHead);
+#endif
 
     // Update the start timer
 
+    /* Release the job list lock */
+    RtlReleaseResource(&JobListLock);
+
     /* Return the new job ID */
     *pJobId = pJob->JobId;
 
@@ -156,6 +162,8 @@ NetrJobDel(
     /* Acquire the job list lock exclusively */
     RtlAcquireResourceExclusive(&JobListLock, TRUE);
 
+    // Cancel the start timer
+
     JobEntry = JobListHead.Flink;
     while (JobEntry != &JobListHead)
     {
@@ -163,9 +171,11 @@ NetrJobDel(
 
         if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
         {
-            // Remove job from the start list
-
-            // Update the start timer
+            /* Remove the job from the start list */
+            RemoveEntryList(&CurrentJob->StartEntry);
+#if 0
+            DumpStartList(&StartListHead);
+#endif
 
             /* Remove the job from the registry */
             DeleteJob(CurrentJob);
@@ -183,6 +193,8 @@ NetrJobDel(
         JobEntry = JobEntry->Flink;
     }
 
+    // Update the start timer
+
     /* Release the job list lock */
     RtlReleaseResource(&JobListLock);
 
@@ -245,7 +257,7 @@ NetrJobEnum(
                           (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR);
             TRACE("dwEntrySize: %lu\n", dwEntrySize);
 
-            if ((PreferedMaximumLength != DWORD_MAX) &&
+            if ((PreferedMaximumLength != ULONG_MAX) &&
                 (dwRequiredSize + dwEntrySize > PreferedMaximumLength))
                 break;
 
@@ -259,7 +271,7 @@ NetrJobEnum(
     TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead);
     TRACE("dwRequiredSize: %lu\n", dwRequiredSize);
 
-    if (PreferedMaximumLength != DWORD_MAX)
+    if (PreferedMaximumLength != ULONG_MAX)
         dwRequiredSize = PreferedMaximumLength;
 
     TRACE("Allocating dwRequiredSize: %lu\n", dwRequiredSize);