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.

122 lines
3.7 KiB

  1. /*****************************************************************/
  2. /** Copyright (C) Microsoft Corp., 1994 **/
  3. /*****************************************************************/
  4. /* SCHED.C -- Miscellaneous scheduling helpers
  5. *
  6. * History:
  7. * gregj 10/17/94 created
  8. */
  9. #include "npcommon.h"
  10. #include <sched.h>
  11. /* FlushInputQueue is a private routine to collect and dispatch all
  12. * messages in the input queue. It returns TRUE if a WM_QUIT message
  13. * was detected in the queue, FALSE otherwise.
  14. */
  15. BOOL FlushInputQueue(volatile DWORD *pidOtherThread)
  16. {
  17. MSG msgTemp;
  18. while (PeekMessage(&msgTemp, NULL, 0, 0, PM_REMOVE)) {
  19. DispatchMessage(&msgTemp);
  20. // If we see a WM_QUIT in the queue, we need to do the same
  21. // sort of thing that a modal dialog does: break out of our
  22. // waiting, and repost the WM_QUIT to the queue so that the
  23. // next message loop up in the app will also see it. We also
  24. // post the message to the server thread's queue so that any
  25. // dialog stack displayed there will be destroyed as well.
  26. if (msgTemp.message == WM_QUIT) {
  27. if (pidOtherThread != NULL && *pidOtherThread != NULL) {
  28. PostThreadMessage(*pidOtherThread, msgTemp.message, msgTemp.wParam, msgTemp.lParam);
  29. }
  30. PostQuitMessage((int)msgTemp.wParam);
  31. return TRUE;
  32. }
  33. }
  34. return FALSE;
  35. }
  36. /* WaitAndYield() waits for the specified object using
  37. * MsgWaitForMultipleObjects. If messages are received,
  38. * they are dispatched and waiting continues. The return
  39. * value is the same as from MsgWaitForMultipleObjects.
  40. */
  41. DWORD WaitAndYield(HANDLE hObject, DWORD dwTimeout, volatile DWORD *pidOtherThread /* = NULL */)
  42. {
  43. DWORD dwTickCount, dwWakeReason, dwTemp;
  44. do {
  45. /* Flush any messages before we wait. This is because
  46. * MsgWaitForMultipleObjects will only return when NEW
  47. * messages are put in the queue.
  48. */
  49. if (FlushInputQueue(pidOtherThread)) {
  50. dwWakeReason = WAIT_TIMEOUT;
  51. break;
  52. }
  53. // in case we handle messages, we want close to a true timeout
  54. if ((dwTimeout != 0) &&
  55. (dwTimeout != (DWORD)-1)) {
  56. // if we can timeout, store the current tick count
  57. // every time through
  58. dwTickCount = GetTickCount();
  59. }
  60. dwWakeReason = MsgWaitForMultipleObjects(1,
  61. &hObject,
  62. FALSE,
  63. dwTimeout,
  64. QS_ALLINPUT);
  65. // if we got a message, dispatch it, then try again
  66. if (dwWakeReason == 1) {
  67. // if we can timeout, see if we did before processing the message
  68. // that way, if we haven't timed out yet, we'll get at least one
  69. // more shot at the event
  70. if ((dwTimeout != 0) &&
  71. (dwTimeout != (DWORD)-1)) {
  72. if ((dwTemp = (GetTickCount()-dwTickCount)) >= dwTimeout) {
  73. // if we timed out, make us drop through
  74. dwWakeReason = WAIT_TIMEOUT;
  75. } else {
  76. // subtract elapsed time from timeout and continue
  77. // (we don't count time spent dispatching message)
  78. dwTimeout -= dwTemp;
  79. }
  80. }
  81. if (FlushInputQueue(pidOtherThread)) {
  82. dwWakeReason = WAIT_TIMEOUT;
  83. break;
  84. }
  85. }
  86. } while (dwWakeReason == 1);
  87. return dwWakeReason;
  88. }
  89. /* WaitAndProcessSends is similar to WaitAndYield, but it only processes
  90. * SendMessage messages, not input messages.
  91. */
  92. DWORD WaitAndProcessSends(HANDLE hObject, DWORD dwTimeout)
  93. {
  94. DWORD dwWakeReason;
  95. do {
  96. dwWakeReason = MsgWaitForMultipleObjects(1,
  97. &hObject,
  98. FALSE,
  99. dwTimeout,
  100. QS_SENDMESSAGE);
  101. // if we got a message, yield, then try again
  102. if (dwWakeReason == 1) {
  103. MSG msgTemp;
  104. PeekMessage(&msgTemp, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD);
  105. }
  106. } while (dwWakeReason == 1);
  107. return dwWakeReason;
  108. }