From dc0b249d1631847e0d62a9368bdd5c5ea6073b71 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 28 Oct 2018 18:12:55 +0100 Subject: [PATCH] [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 cc97f4b46bd..0d6a29ea6a3 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 405a0dd61e1..8fc590ba7fb 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 28e639a5a1c..ba96195839f 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); } } -- 2.17.1