diff --git a/reactos/base/services/schedsvc/job.c b/reactos/base/services/schedsvc/job.c index 8e7a90c8805..89bd28daa34 100644 --- a/reactos/base/services/schedsvc/job.c +++ b/reactos/base/services/schedsvc/job.c @@ -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 */ diff --git a/reactos/base/services/schedsvc/precomp.h b/reactos/base/services/schedsvc/precomp.h index 0da85a0d450..5d472d3fe75 100644 --- a/reactos/base/services/schedsvc/precomp.h +++ b/reactos/base/services/schedsvc/precomp.h @@ -4,6 +4,7 @@ #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H +#include #include #include #include @@ -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 */ diff --git a/reactos/base/services/schedsvc/rpcserver.c b/reactos/base/services/schedsvc/rpcserver.c index e23371ec65a..1ca2b353ee2 100644 --- a/reactos/base/services/schedsvc/rpcserver.c +++ b/reactos/base/services/schedsvc/rpcserver.c @@ -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);