/*++ Copyright (c) 1998 Microsoft Corporation Module Name : w3job.hxx Abstract: This file contains class definition for w3 job objects. Author: Michael Thomas (michth) Jan-02-1998 Revision History: --*/ #ifndef _W3JOBOBJ_H_ #define _W3JOBOBJ_H_ #include "iistypes.hxx" #define MINUTESTOMILISECONDS (1000 * 60) #define SECONDSTO100NANOSECONDS 10000000 #define MINUTESTO100NANOSECONDS (SECONDSTO100NANOSECONDS * 60) // // Job Object Limit Actions // typedef enum _SET_LIMIT_ACTION { SLA_PROCESS_CPU_LIMIT, // Set Per Process CPU Limit SLA_PROCESS_PRIORITY_CLASS, // Set Priority Class SLA_TERMINATE_ALL_PROCESSES, // Terminate all processes in job SLA_JOB_CPU_LIMIT } SET_LIMIT_ACTION, *PSET_LIMIT_ACTION; // // CPU Logging Fields // typedef enum _JOB_OBJECT_LOGGING_FIELDS { JOLF_EVENT, JOLF_INFO_TYPE, JOLF_USER_TIME, JOLF_KERNEL_TIME, JOLF_PAGE_FAULT, JOLF_TOTAL_PROCS, JOLF_ACTIVE_PROCS, JOLF_TERMINATED_PROCS, JOLF_NUM_ELEMENTS } JOB_OBJECT_LOGGING_FIELDS, *PJOB_OBJECT_LOGGING_FIELDS; // // CPU Logging Events // Must be kept in sync with pszarrayJOLE in w3jobobj.cxx // typedef enum _JOB_OBJECT_LOG_EVENTS { JOLE_SITE_START, JOLE_SITE_STOP, JOLE_SITE_PAUSE, JOLE_PERIODIC_LOG, JOLE_RESET_INT_START, JOLE_RESET_INT_STOP, JOLE_RESET_INT_CHANGE, JOLE_LOGGING_INT_START, JOLE_LOGGING_INT_STOP, JOLE_LOGGING_INT_CHANGE, JOLE_EVENTLOG_LIMIT, JOLE_PRIORITY_LIMIT, JOLE_PROCSTOP_LIMIT, JOLE_PAUSE_LIMIT, JOLE_EVENTLOG_LIMIT_RESET, JOLE_PRIORITY_LIMIT_RESET, JOLE_PROCSTOP_LIMIT_RESET, JOLE_PAUSE_LIMIT_RESET, JOLE_NUM_ELEMENTS } JOB_OBJECT_LOG_EVENTS; #define JOLE_SITE_START_STR "Site-Start" #define JOLE_SITE_STOP_STR "Site-Stop" #define JOLE_SITE_PAUSE_STR "Site-Pause" #define JOLE_PERIODIC_LOG_STR "Periodic-Log" #define JOLE_RESET_INT_START_STR "Reset-Interval-Start" #define JOLE_RESET_INT_STOP_STR "Reset-Interval-Stop" #define JOLE_RESET_INT_CHANGE_STR "Reset-Interval-Change" #define JOLE_LOGGING_INT_START_STR "Logging-Interval-Start" #define JOLE_LOGGING_INT_STOP_STR "Logging-Interval-Stop" #define JOLE_LOGGING_INT_CHANGE_STR "Logging_Interval-Change" #define JOLE_EVENTLOG_LIMIT_STR "Eventlog-Limit" #define JOLE_PRIORITY_LIMIT_STR "Priority-Limit" #define JOLE_PROCSTOP_LIMIT_STR "Process-Stop-Limit" #define JOLE_PAUSE_LIMIT_STR "Site-Pause-Limit" #define JOLE_EVENTLOG_LIMIT_RESET_STR "Eventlog-Limit-Reset" #define JOLE_PRIORITY_LIMIT_RESET_STR "Priority-Limit-Reset" #define JOLE_PROCSTOP_LIMIT_RESET_STR "Process-Stop-Limit-Reset" #define JOLE_PAUSE_LIMIT_RESET_STR "Site-Pause-Limit-Reset" // // Process type for CPU Logging // Must be kept in sync with pszarrayJOPT in w3jobobj.cxx // typedef enum _JOB_OBJECT_PROCESS_TYPE { JOPT_CGI, JOPT_APP, JOPT_ALL, JOPT_NUM_ELEMENTS } JOB_OBJECT_PROCESS_TYPE; #define JOPT_CGI_STR "CGI" #define JOPT_APP_STR "Application" #define JOPT_ALL_STR "All" // // The main class for handling job objects. // All job object interactions are via this class. // class W3_JOB_OBJECT { private: // // Job Object // HANDLE m_hJobObject; // Handle to job object DWORD m_dwJobCGICPULimit; // The CGI CPU limit, in seconds CRITICAL_SECTION m_csLock; JOBOBJECT_BASIC_ACCOUNTING_INFORMATION m_jobaiPrevInfo; // The last reset information HRESULT m_dwError; // Initialization error code public: W3_JOB_OBJECT( DWORD dwJobCGICPULimit = NO_W3_CPU_CGI_LIMIT ); ~W3_JOB_OBJECT( void ); // // Job Object // DWORD AddProcessToJob( HANDLE hProcess ); BOOL QueryJobInfo( JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo, BOOL bResetCounters ); // // Data access protection methods // DWORD SetCompletionPort(HANDLE hCompletionPort, PVOID pvCompletionKey); VOID SetJobLimit(IN SET_LIMIT_ACTION slaAction, IN DWORD dwValue, IN LONGLONG llJobCPULimit = 0); dllexp VOID LockThis( VOID ) { EnterCriticalSection(&m_csLock);} dllexp VOID UnlockThis( VOID ) { LeaveCriticalSection(&m_csLock);} VOID ResetCounters( JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo ); VOID IncrementStoppedProcs( VOID ); static VOID SumJobInfo(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiSumInfo, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo1, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo2); static VOID SubtractJobInfo(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiResultInfo, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo1, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *pjobaiInfo2); HRESULT GetInitError() {return m_dwError;}; }; typedef W3_JOB_OBJECT *PW3_JOB_OBJECT; // // Class to set up a completion port and a thread // to monitor it. The monitoring function LimitThreadProc // is hardcoded to handle job object limits. // class W3_LIMIT_JOB_THREAD { private: HANDLE m_hLimitThread; // Handle to thread HANDLE m_hCompletionPort; // Handle to Completion Port DWORD m_dwInitError; W3_LIMIT_JOB_THREAD( void ); VOID TerminateLimitJobThreadThread( void ); DWORD LimitThreadProc ( void ); static W3_LIMIT_JOB_THREAD *m_pljtLimitJobs; public: ~W3_LIMIT_JOB_THREAD( void ); DWORD GetInitError( void ) { return m_dwInitError; }; static DWORD GetLimitJobThread( W3_LIMIT_JOB_THREAD ** ppljtLimitJobs ); static DWORD LimitThreadProcStub ( LPVOID pljtClass ) { return ((W3_LIMIT_JOB_THREAD *)pljtClass)->LimitThreadProc(); }; static VOID StopLimitJobThread( void ); static VOID TerminateLimitJobThread( void ); HANDLE GetCompletionPort ( void ) { return m_hCompletionPort; } }; typedef W3_LIMIT_JOB_THREAD *PW3_LIMIT_JOB_THREAD; // // Class to set up a work item queue for job objects and a thread // to monitor it. The main purpose of this thread is to handle // work items that must not hold the job lock. // typedef enum _JOB_QUEUE_ACTION { JQA_RESTART_ALL_APPS, JQA_TERMINATE_SITE_APPS, JQA_TERMINATE_THREAD } JOB_QUEUE_ACTION, *PJOB_QUEUE_ACTION; typedef struct _JOB_WORK_ITEM { LIST_ENTRY ListEntry; JOB_QUEUE_ACTION jqaAction; PVOID pwsiInstance; PVOID pvParam; } JOB_WORK_ITEM, *PJOB_WORK_ITEM; class W3_JOB_QUEUE { private: HANDLE m_hQueueThread; // Handle to thread DWORD m_dwInitError; CRITICAL_SECTION m_csLock; LIST_ENTRY m_leJobQueue; HANDLE m_hQueueEvent; W3_JOB_QUEUE( void ); dllexp VOID LockThis( VOID ) { EnterCriticalSection(&m_csLock);} dllexp VOID UnlockThis( VOID ) { LeaveCriticalSection(&m_csLock);} static DWORD GetJobQueue( W3_JOB_QUEUE ** ppjqJobQueue ); static W3_JOB_QUEUE *m_pjqJobQueue; DWORD QueueWorkItem_Worker( JOB_QUEUE_ACTION jqaAction, PVOID pwsiInstance, PVOID pvParam, BOOL fQueueAtTail = TRUE); VOID TerminateJobQueueThread( void ); public: ~W3_JOB_QUEUE( void ); DWORD GetInitError( void ) { return m_dwInitError; }; static DWORD QueueThreadProcStub ( LPVOID pjqClass ) { return ((W3_JOB_QUEUE *)pjqClass)->QueueThreadProc(); }; DWORD QueueThreadProc ( void ); static DWORD QueueWorkItem( JOB_QUEUE_ACTION jqaAction, PVOID pwsiInstance, PVOID pvParam); static VOID TerminateJobQueue( void ); static VOID StopJobQueue( void ); }; typedef W3_JOB_QUEUE *PW3_JOB_QUEUE; VOID DeferredQueryAndLogJobInfo( VOID * pContext ); VOID DeferredJobResetInterval( VOID * pContext ); VOID DeferredRestartChangedApplications( VOID * pContext ); // CPU accounting/limits globals // extern DWORD g_dwNumProcessors; #endif // _W3JOBOBJ_H_