[SCHEDSVC] Reschedule a job after it was started
authorEric Kohl <eric.kohl@reactos.org>
Sun, 28 Oct 2018 17:12:55 +0000 (18:12 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 28 Oct 2018 17:12:55 +0000 (18:12 +0100)
- Remove a non-recurring job from the job list after starting it.
- Remove a recurring job from the start list, calculate its next start time and insert it again.
- Calculate the timeout for the next job.

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

index cc97f4b..0d6a29e 100644 (file)
@@ -83,6 +83,87 @@ GetNextJobTimeout(VOID)
 }
 
 
+static
+VOID
+ReScheduleJob(
+    PJOB pJob)
+{
+    /* Remove the job from the start list */
+    RemoveEntryList(&pJob->StartEntry);
+
+    /* No repetition, remove the job */
+    if (pJob->DaysOfMonth == 0 && pJob->DaysOfWeek == 0)
+    {
+        /* Remove the job from the registry */
+        DeleteJob(pJob);
+
+        /* Remove the job from the job list */
+        RemoveEntryList(&pJob->JobEntry);
+        dwJobCount--;
+
+        /* Free the job object */
+        HeapFree(GetProcessHeap(), 0, pJob);
+        return;
+    }
+
+    /* Calculate the next start time */
+    CalculateNextStartTime(pJob);
+
+    /* Insert the job into the start list again */
+    InsertJobIntoStartList(&StartListHead, pJob);
+#if 0
+    DumpStartList(&StartListHead);
+#endif
+}
+
+
+VOID
+RunNextJob(VOID)
+{
+#if 0
+    PROCESS_INFORMATION ProcessInformation;
+    STARTUPINFOW StartupInfo;
+    WCHAR CommandLine[256];
+    BOOL bRet;
+#endif
+    PJOB pNextJob;
+
+    if (IsListEmpty(&StartListHead))
+    {
+        ERR("No job in list!\n");
+        return;
+    }
+
+    pNextJob = CONTAINING_RECORD((&StartListHead)->Flink, JOB, StartEntry);
+
+    ERR("Run job %ld: %S\n", pNextJob->JobId, pNextJob->Command);
+
+#if 0
+    bRet = CreateProcess(NULL,
+                         CommandLine,
+                         NULL,
+                         NULL,
+                         FALSE,
+                         CREATE_NEW_CONSOLE | CREATE_SEPARATE_WOW_VDM,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+    if (bRet == FALSE)
+    {
+        // FIXME: Log the failure!
+    }
+    else
+    {
+        CloseHandle(ProcessInformation.hThread);
+        CloseHandle(ProcessInformation.hProcess);
+    }
+#endif
+
+    ReScheduleJob(pNextJob);
+}
+
+
 static
 VOID
 GetJobName(
@@ -396,27 +477,38 @@ CalculateNextStartTime(
     StartTime.wHour = (WORD)(pJob->JobTime / 3600000);
     StartTime.wMinute = (WORD)((pJob->JobTime % 3600000) / 60000);
 
-    /* Start the job tomorrow */
-    if (Now > pJob->JobTime)
+    if (pJob->DaysOfMonth != 0)
+    {
+         FIXME("Support DaysOfMonth!\n");
+    }
+    else if (pJob->DaysOfWeek != 0)
+    {
+         FIXME("Support DaysOfWeek!\n");
+    }
+    else
     {
-        if (StartTime.wDay + 1 > DaysOfMonth(StartTime.wMonth, StartTime.wYear))
+        /* Start the job tomorrow */
+        if (Now > pJob->JobTime)
         {
-            if (StartTime.wMonth == 12)
+            if (StartTime.wDay + 1 > DaysOfMonth(StartTime.wMonth, StartTime.wYear))
             {
-                StartTime.wDay = 1;
-                StartTime.wMonth = 1;
-                StartTime.wYear++;
+                if (StartTime.wMonth == 12)
+                {
+                    StartTime.wDay = 1;
+                    StartTime.wMonth = 1;
+                    StartTime.wYear++;
+                }
+                else
+                {
+                    StartTime.wDay = 1;
+                    StartTime.wMonth++;
+                }
             }
             else
             {
-                StartTime.wDay = 1;
-                StartTime.wMonth++;
+                StartTime.wDay++;
             }
         }
-        else
-        {
-            StartTime.wDay++;
-        }
     }
 
     TRACE("Next start: %02hu:%02hu %02hu.%02hu.%hu\n", StartTime.wHour,
index 405a0dd..8fc590b 100644 (file)
@@ -60,6 +60,9 @@ extern HANDLE Events[2];
 DWORD
 GetNextJobTimeout(VOID);
 
+VOID
+RunNextJob(VOID);
+
 LONG
 SaveJob(
     PJOB pJob);
index 28e639a..ba96195 100644 (file)
@@ -231,12 +231,19 @@ SchedServiceMain(DWORD argc, LPTSTR *argv)
         else if (dwWait == WAIT_OBJECT_0 + 1)
         {
             TRACE("Update event signaled!\n");
+
+            RtlAcquireResourceShared(&JobListLock, TRUE);
             dwTimeout = GetNextJobTimeout();
+            RtlReleaseResource(&JobListLock);
         }
         else if (dwWait == WAIT_TIMEOUT)
         {
             TRACE("Timeout: Start the next job!\n");
 
+            RtlAcquireResourceExclusive(&JobListLock, TRUE);
+            RunNextJob();
+            dwTimeout = GetNextJobTimeout();
+            RtlReleaseResource(&JobListLock);
         }
     }