Source code of Windows XP (NT5)
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.

205 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. sample\utils.c
  5. Abstract:
  6. The file contains miscellaneous utilities.
  7. --*/
  8. #include "pchsample.h"
  9. #pragma hdrstop
  10. DWORD
  11. QueueSampleWorker(
  12. IN WORKERFUNCTION pfnFunction,
  13. IN PVOID pvContext
  14. )
  15. /*++
  16. Routine Description
  17. This function is called to queue a worker function in a safe fashion;
  18. if cleanup is in progress or if SAMPLE has stopped, this function
  19. discards the work-item.
  20. Locks
  21. Acquires exclusively g_ce.rwlLock
  22. Releases g_ce.rwlLock
  23. Arguments
  24. pfnFunction function to be called
  25. pvContext opaque ptr used in callback
  26. Return Value
  27. NO_ERROR if success
  28. Failure code o/w
  29. --*/
  30. {
  31. DWORD dwErr = NO_ERROR;
  32. BOOL bSuccess = FALSE;
  33. ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
  34. do // breakout loop
  35. {
  36. // cannot queue a work function when SAMPLE has quit or is quitting
  37. if (g_ce.iscStatus != IPSAMPLE_STATUS_RUNNING)
  38. {
  39. dwErr = ERROR_CAN_NOT_COMPLETE;
  40. break;
  41. }
  42. bSuccess = QueueUserWorkItem((LPTHREAD_START_ROUTINE)pfnFunction,
  43. pvContext,
  44. 0); // no flags
  45. if (bSuccess)
  46. g_ce.ulActivityCount++;
  47. else
  48. dwErr = GetLastError();
  49. } while (FALSE);
  50. RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
  51. return dwErr;
  52. }
  53. BOOL
  54. EnterSampleAPI(
  55. )
  56. /*++
  57. Routine Description
  58. This function is called when entering a SAMPLE api, as well as when
  59. entering the input thread and timer thread. It checks to see if SAMPLE
  60. has stopped, and if so it quits; otherwise it increments the count of
  61. active threads.
  62. Locks
  63. Acquires exclusively g_ce.rwlLock
  64. Releases g_ce.rwlLock
  65. Arguments
  66. None
  67. Return Value
  68. TRUE if entered successfully
  69. FALSE o/w
  70. --*/
  71. {
  72. BOOL bEntered = FALSE;
  73. ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
  74. if (g_ce.iscStatus is IPSAMPLE_STATUS_RUNNING)
  75. {
  76. // SAMPLE is running, so continue
  77. g_ce.ulActivityCount++;
  78. bEntered = TRUE;
  79. }
  80. RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
  81. return bEntered;
  82. }
  83. BOOL
  84. EnterSampleWorker(
  85. )
  86. /*++
  87. Routine Description
  88. This function is called when entering a SAMPLE worker-function. Since
  89. there is a lapse between the time a worker-function is queued and the
  90. time the function is actually invoked by a worker thread, this function
  91. must check to see if SAMPLE has stopped or is stopping; if this is the
  92. case, then it decrements the activity count, releases the activity
  93. semaphore, and quits.
  94. Locks
  95. Acquires exclusively g_ce.rwlLock
  96. Releases g_ce.rwlLock
  97. Arguments
  98. None
  99. Return Value
  100. TRUE if entered successfully
  101. FALSE o/w
  102. --*/
  103. {
  104. BOOL bEntered = FALSE;
  105. ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
  106. do // breakout loop
  107. {
  108. // SAMPLE is running, so the function may continue
  109. if (g_ce.iscStatus is IPSAMPLE_STATUS_RUNNING)
  110. {
  111. bEntered = TRUE;
  112. break;
  113. }
  114. // SAMPLE is not running, but it was, so the function must stop
  115. if (g_ce.iscStatus is IPSAMPLE_STATUS_STOPPING)
  116. {
  117. g_ce.ulActivityCount--;
  118. ReleaseSemaphore(g_ce.hActivitySemaphore, 1, NULL);
  119. break;
  120. }
  121. // SAMPLE probably never started. quit
  122. } while (FALSE);
  123. RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
  124. return bEntered;
  125. }
  126. VOID
  127. LeaveSampleWorker(
  128. )
  129. /*++
  130. Routine Description
  131. This function is called when leaving a SAMPLE api or worker function.
  132. It decrements the activity count, and if it detects that SAMPLE has
  133. stopped or is stopping, it releases the activity semaphore.
  134. Locks
  135. Acquires exclusively g_ce.rwlLock
  136. Releases g_ce.rwlLock
  137. Arguments
  138. None
  139. Return Value
  140. TRUE if entered successfully
  141. FALSE o/w
  142. --*/
  143. {
  144. ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
  145. g_ce.ulActivityCount--;
  146. if (g_ce.iscStatus is IPSAMPLE_STATUS_STOPPING)
  147. ReleaseSemaphore(g_ce.hActivitySemaphore, 1, NULL);
  148. RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
  149. }