Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
5.9 KiB

  1. #ifndef __KILL_TIMER_COMPILED__
  2. #define __KILL_TIMER_COMPILED__
  3. #include <wbemidl.h>
  4. #include <wbemutil.h>
  5. #include <cominit.h>
  6. #include <Limits.h>
  7. #include <FlexArry.h>
  8. #include <unk.h>
  9. #include <sync.h>
  10. // used for "forever" or "invalid date"
  11. const FILETIME FILETIME_MAX = {_UI32_MAX, _UI32_MAX};
  12. // something to make FILETIME easier to deal with
  13. // performs casts automagically, allows addition
  14. union WAYCOOL_FILETIME
  15. {
  16. public:
  17. /* CONSTRUCTION */
  18. WAYCOOL_FILETIME(UINT64 ui64 = 0)
  19. { m_ui64 = ui64; }
  20. WAYCOOL_FILETIME(FILETIME ft)
  21. { m_ft = ft; }
  22. /* ASSIGNMENT */
  23. FILETIME& operator= (const FILETIME& other)
  24. { m_ft = other; return m_ft; }
  25. UINT64& operator= (const UINT64& other)
  26. { m_ui64 = other; return m_ui64; }
  27. /* COMPARISON */
  28. bool operator< (const WAYCOOL_FILETIME& other)
  29. { return m_ui64 < other.m_ui64; }
  30. bool operator<= (const WAYCOOL_FILETIME& other)
  31. { return m_ui64 <= other.m_ui64; }
  32. bool operator> (const WAYCOOL_FILETIME& other)
  33. { return m_ui64 > other.m_ui64; }
  34. bool operator>= (const WAYCOOL_FILETIME& other)
  35. { return m_ui64 >= other.m_ui64; }
  36. bool operator== (const WAYCOOL_FILETIME& other)
  37. { return m_ui64 == other.m_ui64; }
  38. bool operator!= (const WAYCOOL_FILETIME& other)
  39. { return m_ui64 != other.m_ui64; }
  40. /* ADDITION & SUBTRACTION */
  41. // remember: units are hundreds of nanoseconds
  42. WAYCOOL_FILETIME operator+ (UINT64 other)
  43. { return WAYCOOL_FILETIME(m_ui64 + other); }
  44. WAYCOOL_FILETIME& operator+= (UINT64 other)
  45. {
  46. m_ui64 += other;
  47. return *this;
  48. }
  49. WAYCOOL_FILETIME operator- (UINT64 other)
  50. { return WAYCOOL_FILETIME(m_ui64 - other); }
  51. WAYCOOL_FILETIME& operator-= (UINT64 other)
  52. {
  53. m_ui64 -= other;
  54. return *this;
  55. }
  56. // += that takes seconds as a parm
  57. WAYCOOL_FILETIME& AddSeconds(UINT64 other)
  58. { return operator+= (SecondsToTicks(other)); }
  59. // -= that takes seconds as a parm
  60. WAYCOOL_FILETIME& SubtractSeconds(UINT64 other)
  61. { return operator-= (SecondsToTicks(other)); }
  62. /* CASTS & CONVERSIONS */
  63. operator UINT64()
  64. { return m_ui64; }
  65. // hey if CString can do it, so can I...
  66. operator UINT64*()
  67. { return &m_ui64; }
  68. operator FILETIME()
  69. { return m_ft; }
  70. static UINT64 SecondsToTicks(UINT64 ticks)
  71. { return (ticks * 10000000ui64); }
  72. /* GET, SET */
  73. FILETIME GetFILETIME(void)
  74. { return m_ft; }
  75. void SetFILETIME(FILETIME ft)
  76. { m_ft = ft; }
  77. UINT64 GetUI64(void)
  78. { return m_ui64; }
  79. void SetUI64(UINT64 ui64)
  80. { m_ui64 = ui64; }
  81. private:
  82. FILETIME m_ft;
  83. UINT64 m_ui64;
  84. };
  85. /* VIRTUAL BASE CLASS CKiller DEFINITION */
  86. // base class for things that can be killed
  87. // chlid classes should only need to add constructor
  88. // and overrid Die()
  89. class CKiller
  90. {
  91. public:
  92. CKiller(FILETIME deathDate, CLifeControl* pControl) :
  93. m_pControl(pControl), m_deathDate(deathDate)
  94. {
  95. if (m_pControl)
  96. m_pControl->ObjectCreated(NULL);
  97. }
  98. virtual ~CKiller()
  99. {
  100. if (m_pControl)
  101. m_pControl->ObjectDestroyed(NULL);
  102. }
  103. // terminate whatever,
  104. virtual void Die() = 0;
  105. // returns true if now is >= death date
  106. bool TimeExpired(const FILETIME& now)
  107. { return (CompareTime(now) < 1); }
  108. // returns 0 if times identical
  109. // -1 if this time is less than now
  110. // +1 if this time is greater than now
  111. int CompareTime(const FILETIME& now)
  112. { return CompareFileTime(&m_deathDate, &now); }
  113. FILETIME GetDeathDate()
  114. { return m_deathDate; }
  115. protected:
  116. private:
  117. FILETIME m_deathDate;
  118. CLifeControl* m_pControl;
  119. };
  120. // class to provide an arbitrary life time to a process
  121. // proc is killed after a specified timeout
  122. // intended as a global manager class
  123. class CKillerTimer
  124. {
  125. public:
  126. /* CONSTRUCTION & INITIALIZATION */
  127. CKillerTimer();
  128. ~CKillerTimer();
  129. HRESULT Initialize(CLifeControl* pControl);
  130. // force shutdown.
  131. void UnloadNOW();
  132. /* VICTIM CONTROL */
  133. // who to kill & when
  134. // generic version of ScheduleAssassination. You can stuff any CKiller derived class in.
  135. // alternatively, the derived class can hide this & expose their own specialized version
  136. HRESULT ScheduleAssassination(CKiller* pKiller);
  137. protected:
  138. // holds CKillers sorted by execution time.
  139. // earliest date first
  140. // array is not sorted "natively:" order is enforced at ScheduleAssaination time.
  141. // TODO: consider use of a container that sorts itself.
  142. CFlexArray m_killers;
  143. /* SYNCHRONIZATION */
  144. // keep us from getting our threads tangled around the array
  145. CCritSec m_csKillers;
  146. // protect worker thread startup & shutdown
  147. CCritSec m_csStartup;
  148. // event signalled when it's time to go away
  149. HANDLE m_hShutdown;
  150. // event signalled when there's a new item in the list
  151. HANDLE m_hNewVictim;
  152. /* THREAD CONTOL */
  153. // called by first thread to notice there isn't a timer thread
  154. HRESULT StartTimer();
  155. // shuts down timer thread
  156. bool KillTimer();
  157. // main killer thread loop
  158. static DWORD WINAPI ThreadStartRoutine(LPVOID lpParameter);
  159. void RunKillerThread();
  160. /* KILLER THREAD'S ROUTINES */
  161. // kill all procs that are older than our expiration date
  162. // called from killer thread only
  163. void KillOffOldGuys(const FILETIME& now);
  164. // decide when to set the waitable timer again.
  165. // called from killer thread only
  166. void RecalcNextKillingSpree(FILETIME& then);
  167. protected:
  168. CLifeControl* m_pControl;
  169. private:
  170. // thread to handle actual waits & kills
  171. HANDLE m_hTimerThread;
  172. };
  173. #endif