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.

702 lines
14 KiB

  1. #ifndef _TTIMER_HXX_
  2. #define _TTIMER_HXX_
  3. template < class TEnum > TEnum operator ++ ( TEnum &sub_phase, int )
  4. {
  5. TEnum old = sub_phase;
  6. sub_phase = static_cast<TEnum>( static_cast<int>(sub_phase) + 1 );
  7. return( old );
  8. }
  9. class CTimerTest : public PTimerCallback
  10. {
  11. public:
  12. CTimerTest()
  13. {
  14. _fInitialized = FALSE;
  15. _cftExpected = 0;
  16. _hEvent = NULL;
  17. _ptszName = NULL;
  18. }
  19. virtual ~CTimerTest()
  20. {
  21. UnInitialize();
  22. }
  23. public:
  24. void Initialize(PTimerCallback *pTimerCallback,
  25. const TCHAR *ptszName,
  26. ULONG ulTimerContext,
  27. ULONG ulPeriodInSeconds,
  28. CNewTimer::TimerRetryType retrytype,
  29. ULONG ulLowerRetryTime,
  30. ULONG ulUpperRetryTime,
  31. ULONG ulMaxLifetime );
  32. void UnInitialize()
  33. {
  34. if( _fInitialized )
  35. {
  36. _timer.Cancel();
  37. _timer.UnInitialize();
  38. _fInitialized = FALSE;
  39. }
  40. }
  41. public:
  42. void WaitForTestToComplete()
  43. {
  44. if( 0xffffffff == WaitForSingleObjectEx( _hEvent, INFINITE, FALSE ))
  45. {
  46. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't wait for event")));
  47. TrkRaiseLastError( );
  48. }
  49. }
  50. void MarkTestCompleted()
  51. {
  52. if( !SetEvent( _hEvent ))
  53. TrkRaiseLastError( );
  54. }
  55. void EnsureTimerIsStopped( )
  56. {
  57. _tprintf( TEXT(" Verifying that timer is stopped (%ds)\n"),
  58. g_ulDefaultPeriod * 2 );
  59. VerifyRegistryDataRemoved();
  60. Sleep( g_ulDefaultPeriod * 2 * 1000 );
  61. }
  62. void SetTimerRegistryValue( const TCHAR *ptszName,
  63. const CFILETIME &cftSet, const CFILETIME cftDue,
  64. ULONG ulRetry );
  65. void VerifyRegistryDataCorrect();
  66. void VerifyRegistryDataRemoved();
  67. public:
  68. void SetSingleShot( const CFILETIME &cftExpected = 0 )
  69. {
  70. if( 0 != cftExpected )
  71. _cftExpected = cftExpected;
  72. else
  73. {
  74. _cftExpected = CFILETIME();
  75. _cftExpected.IncrementSeconds( _ulPeriod );
  76. }
  77. _timer.SetSingleShot();
  78. TrkLog(( TRKDBG_TIMER, TEXT("%s"), CDebugString( _timer )._tsz ));
  79. if( _ptszName )
  80. VerifyRegistryDataCorrect();
  81. }
  82. void SetRecurring( const CFILETIME &cftExpected = 0 )
  83. {
  84. if( 0 != cftExpected )
  85. _cftExpected = cftExpected;
  86. else
  87. {
  88. _cftExpected = CFILETIME();
  89. _cftExpected.IncrementSeconds( _ulPeriod );
  90. }
  91. _timer.SetRecurring();
  92. if( _ptszName )
  93. VerifyRegistryDataCorrect();
  94. }
  95. protected:
  96. BOOL _fInitialized;
  97. CNewTimer _timer;
  98. ULONG _ulPeriod;
  99. const TCHAR * _ptszName;
  100. CFILETIME _cftExpected;
  101. HANDLE _hEvent;
  102. };
  103. class CTimerTest0 : public CTimerTest
  104. {
  105. public:
  106. CTimerTest0()
  107. {
  108. }
  109. ~CTimerTest0()
  110. {
  111. UnInitialize();
  112. }
  113. public:
  114. void Initialize()
  115. {
  116. _tprintf( TEXT("Starting a timer with a given due time (%ds)\n"), g_ulDefaultPeriod );
  117. _ulPeriod = g_ulDefaultPeriod;
  118. CTimerTest::Initialize( this, NULL, 0,
  119. _ulPeriod, CNewTimer::NO_RETRY, 0, 0, 0 );
  120. }
  121. public:
  122. void Set()
  123. {
  124. SetSingleShot();
  125. }
  126. private:
  127. TimerContinuation Timer( ULONG ulTimerContext );
  128. }; // class CTimerTest0
  129. class CTimerTest1 : public CTimerTest
  130. {
  131. private:
  132. enum SUB_PHASE_ENUM
  133. {
  134. INITIAL = 1,
  135. FIRST_RECURRENCE = 2,
  136. FIRST_RETRY = 3,
  137. SECOND_RETRY = 4,
  138. THIRD_RETRY = 5,
  139. FOURTH_RETRY = 6,
  140. SECOND_RECURRENCE = 7,
  141. LAST_RETRY = 8,
  142. FINAL = 9
  143. };
  144. public:
  145. CTimerTest1()
  146. {
  147. _SubPhase = INITIAL;
  148. }
  149. ~CTimerTest1()
  150. {
  151. UnInitialize();
  152. }
  153. public:
  154. void Initialize()
  155. {
  156. _tprintf( TEXT("Starting a persistent, recurring, backoff-retry (%d-%ds) timer (%ds)\n"),
  157. g_ulMinRetry, g_ulMaxRetry, g_ulDefaultPeriod );
  158. _ulPeriod = g_ulDefaultPeriod;
  159. CTimerTest::Initialize( this, L"Timer1", 1,
  160. _ulPeriod, CNewTimer::RETRY_WITH_BACKOFF, g_ulMinRetry, g_ulMaxRetry, 0 );
  161. }
  162. public:
  163. void Set()
  164. {
  165. SetRecurring();
  166. }
  167. private:
  168. TimerContinuation Timer( ULONG ulTimerContext );
  169. private:
  170. SUB_PHASE_ENUM _SubPhase;
  171. }; // class CTimerTest1
  172. class CTimerTest2 : public CTimerTest
  173. {
  174. private:
  175. enum SUB_PHASE_ENUM
  176. {
  177. INITIAL = 1,
  178. RESET = 2,
  179. FINAL = 3
  180. };
  181. public:
  182. CTimerTest2()
  183. {
  184. _SubPhase = INITIAL;
  185. }
  186. ~CTimerTest2()
  187. {
  188. UnInitialize();
  189. }
  190. public:
  191. void Initialize()
  192. {
  193. _tprintf( TEXT("Starting a persistent, recurring, non-retrying timer (%ds)\n"),
  194. g_ulDefaultPeriod );
  195. _ulPeriod = g_ulDefaultPeriod;
  196. CTimerTest::Initialize( this, L"Timer2", 2,
  197. _ulPeriod, CNewTimer::NO_RETRY, 0, 0, 0 );
  198. }
  199. public:
  200. void Set()
  201. {
  202. SetRecurring();
  203. }
  204. private:
  205. TimerContinuation Timer( ULONG ulTimerContext );
  206. private:
  207. SUB_PHASE_ENUM _SubPhase;
  208. }; // class CTimerTest1
  209. class CTimerTest3 : public CTimerTest
  210. {
  211. private:
  212. enum SUB_PHASE_ENUM
  213. {
  214. INITIAL = 1,
  215. FINAL = 2
  216. };
  217. public:
  218. CTimerTest3()
  219. {
  220. _SubPhase = INITIAL;
  221. }
  222. ~CTimerTest3()
  223. {
  224. UnInitialize();
  225. }
  226. public:
  227. void Initialize()
  228. {
  229. CFILETIME cftNow;
  230. LONG lRet;
  231. _tprintf( TEXT("Continuing a persistent timer (0s)\n") );
  232. SetTimerRegistryValue( TEXT("Timer3"), 0, cftNow-1, 0 );
  233. // We set a period, but it should really go off immediately because
  234. // of the registry value we just set.
  235. _ulPeriod = g_ulDefaultPeriod;
  236. CTimerTest::Initialize( this, // PTimerCallback
  237. L"Timer3", // Timer name
  238. 3, // Timer context
  239. _ulPeriod, // Period in seconds
  240. CNewTimer::NO_RETRY,
  241. 0, 0, 0 ); // Lower, upper, max retry times.
  242. }
  243. public:
  244. void Set()
  245. {
  246. SetSingleShot( CFILETIME() - 1 );
  247. }
  248. private:
  249. TimerContinuation Timer( ULONG ulTimerContext );
  250. private:
  251. SUB_PHASE_ENUM _SubPhase;
  252. }; // class CTimerTest1
  253. class CTimerTest4 : public CTimerTest
  254. {
  255. private:
  256. enum SUB_PHASE_ENUM
  257. {
  258. INITIAL = 1,
  259. SECOND = 2,
  260. THIRD = 3,
  261. FOURTH = 4,
  262. FINAL = 5
  263. };
  264. public:
  265. CTimerTest4()
  266. {
  267. _SubPhase = INITIAL;
  268. }
  269. ~CTimerTest4()
  270. {
  271. UnInitialize();
  272. }
  273. public:
  274. void Initialize()
  275. {
  276. _tprintf( TEXT("Starting a non-persistent timer with max lifetime\n") );
  277. _ulPeriod = g_ulDefaultPeriod;
  278. CTimerTest::Initialize( this, // PTimerCallback
  279. NULL, // Timer name
  280. 4, // Timer context
  281. _ulPeriod, // Period in seconds
  282. CNewTimer::RETRY_WITH_BACKOFF,
  283. g_ulDefaultPeriod/2, // Min retry
  284. g_ulDefaultPeriod * 2, // Max retry
  285. // Max lifetime
  286. g_ulDefaultPeriod + g_ulDefaultPeriod/2 + g_ulDefaultPeriod + 2*g_ulDefaultPeriod + g_ulDefaultPeriod/4 );
  287. }
  288. public:
  289. void Set()
  290. {
  291. SetSingleShot();
  292. }
  293. private:
  294. TimerContinuation Timer( ULONG ulTimerContext );
  295. private:
  296. SUB_PHASE_ENUM _SubPhase;
  297. }; // class CTimerTest4
  298. class CTimerTest5 : public CTimerTest
  299. {
  300. private:
  301. enum SUB_PHASE_ENUM
  302. {
  303. INITIAL = 1
  304. };
  305. public:
  306. CTimerTest5()
  307. {
  308. _SubPhase = INITIAL;
  309. }
  310. ~CTimerTest5()
  311. {
  312. UnInitialize();
  313. }
  314. public:
  315. void Initialize()
  316. {
  317. _tprintf( TEXT("Starting a generic timer (%ds)\n"), g_ulDefaultPeriod * 2 );
  318. _ulPeriod = g_ulDefaultPeriod * 2;
  319. CTimerTest::Initialize( this, // PTimerCallback
  320. NULL, // Timer name
  321. 5, // Timer context
  322. _ulPeriod, // Period in seconds
  323. CNewTimer::NO_RETRY,
  324. 0, 0, 0 ); // Min, max retry, max lifetime
  325. }
  326. public:
  327. void Set()
  328. {
  329. SetSingleShot();
  330. }
  331. private:
  332. TimerContinuation Timer( ULONG ulTimerContext );
  333. private:
  334. SUB_PHASE_ENUM _SubPhase;
  335. }; // class CTimerTest4
  336. class CTimerTest6 : public CTimerTest
  337. {
  338. private:
  339. enum SUB_PHASE_ENUM
  340. {
  341. INITIAL = 1,
  342. FIRST_RECURRENCE = 2,
  343. FIRST_RETRY = 3,
  344. SECOND_RETRY = 4,
  345. THIRD_RETRY = 5,
  346. FOURTH_RETRY = 6,
  347. FINAL = 7
  348. };
  349. public:
  350. CTimerTest6()
  351. {
  352. _cftLower = 0;
  353. _cftUpper = 0;
  354. _cftLastSet = 0;
  355. _SubPhase = INITIAL;
  356. }
  357. ~CTimerTest6()
  358. {
  359. UnInitialize();
  360. }
  361. public:
  362. void Initialize()
  363. {
  364. _tprintf( TEXT("Continuing a persistent, recurring, random-retry (%d-%ds) timer (%ds)\n"),
  365. g_ulMinRetry, g_ulMaxRetry, g_ulDefaultPeriod );
  366. _ulPeriod = g_ulDefaultPeriod;
  367. CFILETIME cftDue;
  368. cftDue.IncrementSeconds( _ulPeriod );
  369. SetTimerRegistryValue( TEXT("Timer6"), 0, cftDue, 0 );
  370. TrkLog(( TRKDBG_ERROR, TEXT("Timer6 due at %x"), cftDue.LowDateTime() ));
  371. CTimerTest::Initialize( this, TEXT("Timer6"), 6,
  372. _ulPeriod,
  373. CNewTimer::RETRY_RANDOMLY,
  374. g_ulMinRetry, g_ulMaxRetry,
  375. 0 ); // No max lifetime
  376. }
  377. public:
  378. void Set()
  379. {
  380. CFILETIME cftExpected;
  381. cftExpected.IncrementSeconds( _ulPeriod );
  382. TrkLog(( TRKDBG_ERROR, TEXT("Timer6 due at %x"), cftExpected.LowDateTime() ));
  383. SetRecurring( cftExpected );
  384. }
  385. private:
  386. TimerContinuation Timer( ULONG ulTimerContext );
  387. private:
  388. CFILETIME _cftLower, _cftUpper, _cftLastSet;
  389. SUB_PHASE_ENUM _SubPhase;
  390. };
  391. class CTimerTest7 : public CTimerTest
  392. {
  393. private:
  394. enum SUB_PHASE_ENUM
  395. {
  396. INITIAL = 1,
  397. FINAL = 2,
  398. };
  399. public:
  400. CTimerTest7()
  401. {
  402. _SubPhase = INITIAL;
  403. }
  404. ~CTimerTest7()
  405. {
  406. UnInitialize();
  407. }
  408. public:
  409. void Initialize()
  410. {
  411. _ulPeriod = g_ulDefaultPeriod;
  412. _tprintf( TEXT("Starting a retrying (%d-%ds) timer (%ds)\n"), _ulPeriod*2, _ulPeriod*4, _ulPeriod );
  413. CTimerTest::Initialize( this, // PTimerCallback
  414. NULL, // Timer name
  415. 7, // Timer context
  416. _ulPeriod, // Period in seconds
  417. CNewTimer::RETRY_WITH_BACKOFF,
  418. _ulPeriod*2, _ulPeriod*4, // Min/max retry
  419. 0 ); // No max lifetime
  420. }
  421. public:
  422. void Set()
  423. {
  424. SetSingleShot();
  425. }
  426. private:
  427. TimerContinuation Timer( ULONG ulTimerContext );
  428. private:
  429. SUB_PHASE_ENUM _SubPhase;
  430. }; // class CTimerTest7
  431. class CTimerTest8 : public CTimerTest
  432. {
  433. private:
  434. enum SUB_PHASE_ENUM
  435. {
  436. INITIAL = 1,
  437. FIRST_RETRY = 2,
  438. FINAL = 3
  439. };
  440. public:
  441. CTimerTest8()
  442. {
  443. _SubPhase = INITIAL;
  444. }
  445. ~CTimerTest8()
  446. {
  447. UnInitialize();
  448. }
  449. public:
  450. void Initialize()
  451. {
  452. _ulPeriod = g_ulDefaultPeriod;
  453. _tprintf( TEXT("Continuing a retrying timer which was already in retry mode\n") );
  454. CFILETIME cftDue, cftSet;
  455. cftSet.DecrementSeconds( _ulPeriod * 2 ); // A regular period, and have the first retry, have already passed
  456. cftDue.IncrementSeconds( _ulPeriod );
  457. SetTimerRegistryValue( TEXT("Timer8"), cftSet, cftDue, _ulPeriod*2 );
  458. CTimerTest::Initialize( this, // PTimerCallback
  459. TEXT("Timer8"), // Timer name
  460. 8, // Timer context
  461. _ulPeriod, // Period in seconds
  462. CNewTimer::RETRY_WITH_BACKOFF,
  463. _ulPeriod*2, _ulPeriod*4, // Min/max retry
  464. // The original period, two retries (2/4) and a retry up to the max lifetime
  465. _ulPeriod*(1+2+4+1) );
  466. }
  467. public:
  468. void Set()
  469. {
  470. CFILETIME cftExpected;
  471. cftExpected.IncrementSeconds( _ulPeriod );
  472. SetSingleShot( cftExpected );
  473. }
  474. private:
  475. TimerContinuation Timer( ULONG ulTimerContext );
  476. private:
  477. SUB_PHASE_ENUM _SubPhase;
  478. }; // class CTimerTest8
  479. #endif // #ifndef _TTIMER_HXX_