https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dc0b249d1631847e0d62a…
commit dc0b249d1631847e0d62a9368bdd5c5ea6073b71
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Oct 28 18:12:55 2018 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Oct 28 18:12:55 2018 +0100
[SCHEDSVC] Reschedule a job after it was started
- 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 | 118 +++++++++++++++++++++++++++++++++-----
base/services/schedsvc/precomp.h | 3 +
base/services/schedsvc/schedsvc.c | 7 +++
3 files changed, 115 insertions(+), 13 deletions(-)
diff --git a/base/services/schedsvc/job.c b/base/services/schedsvc/job.c
index cc97f4b46b..0d6a29ea6a 100644
--- a/base/services/schedsvc/job.c
+++ b/base/services/schedsvc/job.c
@@ -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,
diff --git a/base/services/schedsvc/precomp.h b/base/services/schedsvc/precomp.h
index 405a0dd61e..8fc590ba7f 100644
--- a/base/services/schedsvc/precomp.h
+++ b/base/services/schedsvc/precomp.h
@@ -60,6 +60,9 @@ extern HANDLE Events[2];
DWORD
GetNextJobTimeout(VOID);
+VOID
+RunNextJob(VOID);
+
LONG
SaveJob(
PJOB pJob);
diff --git a/base/services/schedsvc/schedsvc.c b/base/services/schedsvc/schedsvc.c
index 28e639a5a1..ba96195839 100644
--- a/base/services/schedsvc/schedsvc.c
+++ b/base/services/schedsvc/schedsvc.c
@@ -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);
}
}