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.

293 lines
9.5 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_T123PSTN);
  3. /* Timer.cpp
  4. *
  5. * Copyright (c) 1993-1995 by DataBeam Corporation, Lexington, KY
  6. *
  7. * Abstract:
  8. * This is the implementation file for the Timer class
  9. *
  10. * Private Instance Variables:
  11. * Maximum_Timer_Events - Maximum number of timers maintained
  12. * by this class
  13. * Timer_Memory - Base address of our TimerEvent
  14. * structure memory
  15. * Timer_Event_Table - Address of first structure in
  16. * Timer_Memory
  17. * Timer_Event_Count - Number of timers active
  18. * Timer_Event_Free_Stack - Holds numbers of available timers
  19. * First_Timer_Event_In_Chain - Number of first timer in the chain
  20. * Last_Timer_Value - Last time that we got from Windows
  21. * Timer_Info - Windows structure that holds the
  22. * current time.
  23. *
  24. * Caveats:
  25. * None
  26. *
  27. * Author:
  28. * James P. Galvin
  29. * James W. Lawwill
  30. */
  31. #include <windowsx.h>
  32. #include "timer.h"
  33. /*
  34. * Timer (void)
  35. *
  36. * Public
  37. *
  38. * Functional Description:
  39. * This is the constructor for the timer class. This procedure gets
  40. * thc current Windows system time.
  41. */
  42. Timer::Timer (void) :
  43. Timer_List (TRANSPORT_HASHING_BUCKETS),
  44. Timer_Event_Free_Stack ()
  45. {
  46. /*
  47. ** Get the current time from Windows
  48. */
  49. Last_Timer_Value = GetTickCount ();
  50. Maximum_Timer_Events = 0;
  51. Timer_Event_Count = 0;
  52. First_Timer_Event_In_Chain=NULL;
  53. }
  54. /*
  55. * ~Timer (void)
  56. *
  57. * Public
  58. *
  59. * Functional Description:
  60. * This is the destructor for the timer class. This routine frees all
  61. * memory associated with timer events.
  62. */
  63. Timer::~Timer (void)
  64. {
  65. PTimerEvent lpTimerEv;
  66. Timer_List.reset();
  67. while (Timer_List.iterate ((PDWORD_PTR) &lpTimerEv))
  68. delete lpTimerEv;
  69. }
  70. /*
  71. * TimerEventHandle Timer::CreateTimerEvent (
  72. * ULONG timer_duration,
  73. * USHORT control_flags,
  74. * IObject * object_ptr,
  75. * PTimerFunction timer_func_ptr)
  76. *
  77. * Public
  78. *
  79. * Functional Description:
  80. * This routine is called to create a timer event. The routine stores the
  81. * information passed-in in a TimerEvent structure. When the timer expires
  82. * the function will be called.
  83. *
  84. */
  85. TimerEventHandle Timer::CreateTimerEvent
  86. (
  87. ULONG timer_duration,
  88. USHORT control_flags,
  89. IObject *object_ptr,
  90. PTimerFunction timer_func_ptr
  91. )
  92. {
  93. TimerEventHandle timer_event=NULL;
  94. PTimerEvent next_timer_event;
  95. PTimerEvent timer_event_ptr;
  96. /*
  97. ** Get the current time from Windows
  98. */
  99. Last_Timer_Value = GetTickCount ();
  100. if (Maximum_Timer_Events > Timer_Event_Count)
  101. {
  102. /*
  103. ** Get the next available handle from the free stack
  104. */
  105. timer_event = (TimerEventHandle) Timer_Event_Free_Stack.get();
  106. Timer_Event_Count++;
  107. }
  108. else
  109. {
  110. /*
  111. ** Assign the timer event counter to the handle
  112. */
  113. timer_event = ++Timer_Event_Count;
  114. Maximum_Timer_Events++;
  115. }
  116. /*
  117. ** If this is the first event to be created, keep track of it
  118. ** so when we iterate through the list, we will know where to
  119. ** start.
  120. */
  121. timer_event_ptr = new TimerEvent;
  122. if (First_Timer_Event_In_Chain == NULL)
  123. {
  124. First_Timer_Event_In_Chain = timer_event_ptr;
  125. next_timer_event = NULL;
  126. }
  127. else
  128. {
  129. next_timer_event = First_Timer_Event_In_Chain;
  130. First_Timer_Event_In_Chain -> previous_timer_event =
  131. timer_event_ptr;
  132. }
  133. First_Timer_Event_In_Chain = timer_event_ptr;
  134. Timer_List.insert ((DWORD_PTR) timer_event, (DWORD_PTR) timer_event_ptr);
  135. /*
  136. ** Fill in the TimerEvent structure
  137. */
  138. timer_event_ptr->event_handle=timer_event;
  139. timer_event_ptr->timer_duration = timer_duration;
  140. timer_event_ptr->total_duration = timer_duration;
  141. timer_event_ptr->object_ptr = object_ptr;
  142. timer_event_ptr->timer_func_ptr = timer_func_ptr;
  143. timer_event_ptr->control_flags = control_flags | TIMER_EVENT_IN_USE;
  144. timer_event_ptr->next_timer_event = next_timer_event;
  145. timer_event_ptr->previous_timer_event = NULL;
  146. return (timer_event);
  147. }
  148. /*
  149. * TimerError Timer::DeleteTimerEvent (TimerEventHandle timer_event)
  150. *
  151. * Public
  152. *
  153. * Functional Description:
  154. * This routine is called by the user to delete a timer event that is
  155. * currently active.
  156. */
  157. TimerError Timer::DeleteTimerEvent (TimerEventHandle timer_event)
  158. {
  159. TimerError return_value;
  160. PTimerEvent timer_event_ptr;
  161. PTimerEvent previous_timer_event_ptr;
  162. PTimerEvent next_timer_event_ptr;
  163. if (Timer_List.find ((DWORD_PTR) timer_event, (PDWORD_PTR) &timer_event_ptr) == FALSE)
  164. return_value = TIMER_INVALID_TIMER_HANDLE;
  165. else
  166. {
  167. Timer_List.remove ((DWORD) timer_event);
  168. if (!(timer_event_ptr->control_flags & TIMER_EVENT_IN_USE))
  169. return_value = TIMER_INVALID_TIMER_HANDLE;
  170. else
  171. {
  172. if (timer_event_ptr->previous_timer_event == NULL)
  173. First_Timer_Event_In_Chain =
  174. timer_event_ptr->next_timer_event;
  175. else
  176. {
  177. previous_timer_event_ptr =
  178. timer_event_ptr->previous_timer_event;
  179. previous_timer_event_ptr->next_timer_event =
  180. timer_event_ptr->next_timer_event;
  181. }
  182. if (timer_event_ptr->next_timer_event != NULL)
  183. {
  184. next_timer_event_ptr =
  185. timer_event_ptr->next_timer_event;
  186. next_timer_event_ptr->previous_timer_event =
  187. timer_event_ptr->previous_timer_event;
  188. }
  189. delete timer_event_ptr;
  190. Timer_Event_Free_Stack.append ((DWORD) timer_event);
  191. --Timer_Event_Count;
  192. return_value = TIMER_NO_ERROR;
  193. }
  194. }
  195. return (return_value);
  196. }
  197. /*
  198. * void Timer::ProcessTimerEvents (void)
  199. *
  200. * Public
  201. *
  202. * Functional Description:
  203. * This routine MUST be called frequently and regularly so that we can
  204. * manage our timers. This function gets the current system time and
  205. * goes through each of the timers to see which have expired. If a timer
  206. * has expired, we call the function associated with it. Upon return,
  207. * if the timer was marked as a one-shot event, we remove it from our
  208. * list of timers.
  209. */
  210. void Timer::ProcessTimerEvents (void)
  211. {
  212. TimerEventHandle timer_event;
  213. TimerEventHandle next_timer_event;
  214. PTimerEvent timer_event_ptr;
  215. IObject * object_ptr;
  216. PTimerFunction timer_func_ptr;
  217. ULONG timer_increment;
  218. DWORD timer_value;
  219. if (!First_Timer_Event_In_Chain)
  220. return;
  221. /*
  222. ** Get the current time
  223. */
  224. timer_value = GetTickCount ();
  225. timer_increment = timer_value - Last_Timer_Value;
  226. Last_Timer_Value = timer_value;
  227. next_timer_event = First_Timer_Event_In_Chain->event_handle;
  228. /*
  229. ** Go through each of the timer events to see if they have expired
  230. */
  231. while (Timer_List.find ((DWORD_PTR) next_timer_event, (PDWORD_PTR) &timer_event_ptr))
  232. {
  233. timer_event = timer_event_ptr->event_handle;
  234. /*
  235. ** Has the timer expired?
  236. */
  237. if (timer_event_ptr->timer_duration <= timer_increment)
  238. {
  239. object_ptr = timer_event_ptr->object_ptr;
  240. timer_func_ptr = timer_event_ptr->timer_func_ptr;
  241. /*
  242. ** Call the function before deleting...
  243. ** otherwise the function could manipulate the list
  244. ** and we wouldn't know if the one we're pointing to
  245. ** is still valid
  246. */
  247. (object_ptr->*timer_func_ptr) (timer_event);
  248. // Get the next timer_event_handle
  249. if (timer_event_ptr->next_timer_event)
  250. next_timer_event = timer_event_ptr->next_timer_event->event_handle;
  251. else
  252. next_timer_event = NULL;
  253. if (timer_event_ptr->control_flags & TIMER_EVENT_ONE_SHOT)
  254. DeleteTimerEvent (timer_event);
  255. else
  256. timer_event_ptr->timer_duration =
  257. timer_event_ptr->total_duration;
  258. }
  259. else
  260. {
  261. // Get the next timer_event_handle
  262. if (timer_event_ptr->next_timer_event)
  263. next_timer_event = timer_event_ptr->next_timer_event->event_handle;
  264. else
  265. next_timer_event = NULL;
  266. timer_event_ptr->timer_duration -= timer_increment;
  267. }
  268. }
  269. }
  270.