Книга: Системное программирование в среде Windows

Получение номера задачи

Получение номера задачи

Следующие три программы представляют три отдельные функции управления задачами. Все эти функции включены в единый файл JobMgt.c, содержащий все исходные тексты.

Первая из них, программа 6.4, представляет функцию Get JobNumber. Обратите внимание на использование блокирования файлов, а также обработчиков завершения, осуществляющих разблокирование файлов. Эта методика обеспечивает защиту от исключений и непреднамеренного обхода вызова функции разблокирования файлов. Переходы такого рода могут быть случайно вставлены в процессе сопровождения кода, даже если исходная программа корректна. Обратите также внимание на блокирование попыток записи за пределами конца файла в тех случаях, когда файл должен быть расширен за счет добавления новой записи.

Программа 6.4. JobMgt: создание информации о новой задаче 

/* Вспомогательная функция управления задачами. */
#include "EvryThng.h"
#include "JobMgt.h" /* Листинг приведен в приложении А. */
void GetJobMgtFileName (LPTSTR);
LONG GetJobNumber(PROCESS_INFORMATION *pProcessInfo, LPCTSTR Command)
/* Создать номер задачи для нового процесса и ввести информацию о новом процессе в базу данных задачи. */
{
 HANDLE hJobData, hProcess;
 JM_JOB JobRecord;
 DWORD JobNumber = 0, nXfer, ExitCode, FsLow, FsHigh;
 TCHAR JobMgtFileName[MAX_PATH];
 OVERLAPPED RegionStart;
 if (!GetJobMgtFileName(JobMgtFileName)) return –1;
 /* Предоставление результата в виде строки "tmpUserName.JobMgt" */
 hJobData = CreateFile(JobMgtFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 if (hJobData == INVALID_HANDLE_VALUE) return –1;
 /* Блокировать весь файл плюс одну возможную запись для получения исключительного доступа. */
 RegionStart.Offset = 0;
 RegionStart.OffsetHigh = 0;
 RegionStart.hEvent = (HANDLE)0;
 FsLow = GetFileSize(hJobData, &FsHigh);
 LockFileEx(hJobData, LOCKFILE_EXCLUSIVE_LOCK, 0, FsLow + SJM_JOB, 0, &RegionStart);
 __try {
  /* Чтение записи для нахождения пустого сегмента. */
  while(ReadFile(hJobData, &JobRecord, SJM_JOB, &nXfer, NULL) && (nXfer > 0)) {
   if (JobRecord.ProcessId == 0) break;
   hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, JobRecord.ProcessId);
   if (hProcess == NULL) break;
   if (GetExitCodeProcess(hProcess, &ExitCode) && (ExitCode != STILL_ACTIVE)) break;
   JobNumber++;
  } 
  /* Либо найден пустой сегмент, либо мы находимся в конце файла и должны создать новый сегмент. */
  if (nXfer != 0) /* Не конец файла. Резервировать. */
   SetFilePointer(hJobData, –(LONG)SJM_JOB, NULL, FILE_CURRENT);
  JobRecord.ProcessId = pProcessInfo->dwProcessId;
  _tcsnccpy(JobRecord.CommandLine, Command, MAX_PATH);
  WriteFile(hJobData, &JobRecord, SJM_JOB, &nXfer, NULL);
 } /* Конец try-блока. */
 __finally {
  UnlockFileEx(hJobData, 0, FsLow + SJM_JOB, 0, &RegionStart);
  CloseHandle(hJobData);
 }
 return JobNumber + 1;
}

Оглавление книги


Генерация: 1.221. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз