[SCHEDSVC]

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
This commit is contained in:
Eric Kohl 2017-04-15 10:33:29 +00:00
parent 5657d83d0e
commit 6de65ddcea
3 changed files with 124 additions and 19 deletions

View 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, &pJob->StartTime);
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;
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 */

View 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 */

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