[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.
This commit is contained in:
Eric Kohl 2018-10-28 18:12:55 +01:00
parent b062d28bc6
commit dc0b249d16
3 changed files with 115 additions and 13 deletions

View 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)
{
if (StartTime.wDay + 1 > DaysOfMonth(StartTime.wMonth, StartTime.wYear))
FIXME("Support DaysOfMonth!\n");
}
else if (pJob->DaysOfWeek != 0)
{
FIXME("Support DaysOfWeek!\n");
}
else
{
/* 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,

View file

@ -60,6 +60,9 @@ extern HANDLE Events[2];
DWORD
GetNextJobTimeout(VOID);
VOID
RunNextJob(VOID);
LONG
SaveJob(
PJOB pJob);

View 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);
}
}