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.

122 lines
2.9 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: WaitUtil.h
  6. //
  7. // Description:
  8. //
  9. // IU wait message utility library
  10. //
  11. //=======================================================================
  12. #include "WaitUtil.h"
  13. DWORD WaitAndPumpMessages(DWORD nCount, LPHANDLE pHandles, DWORD dwWakeMask)
  14. {
  15. DWORD dwWaitResult;
  16. MSG msg;
  17. while (TRUE)
  18. {
  19. dwWaitResult = MsgWaitForMultipleObjects(nCount, pHandles, FALSE, 1000, dwWakeMask);
  20. if (dwWaitResult <= WAIT_OBJECT_0 + nCount - 1)
  21. {
  22. return dwWaitResult;
  23. }
  24. if (WAIT_OBJECT_0 + nCount == dwWaitResult)
  25. {
  26. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  27. {
  28. TranslateMessage(&msg);
  29. DispatchMessage(&msg);
  30. }
  31. }
  32. }
  33. return dwWaitResult;
  34. }
  35. DWORD MyMsgWaitForMultipleObjects(DWORD nCount, LPHANDLE pHandles, BOOL fWaitAll, DWORD dwMilliseconds, DWORD dwWakeMask)
  36. {
  37. DWORD dwTickStart;
  38. DWORD dwWaitResult;
  39. DWORD dwLoopMS = 250; // default 250 ms timeout for MsgWaitForMultipleObjects
  40. MSG msg;
  41. dwTickStart = GetTickCount();
  42. if (dwLoopMS > dwMilliseconds)
  43. {
  44. //
  45. // Never wait more than dwMilliseconds
  46. //
  47. dwLoopMS = dwMilliseconds;
  48. }
  49. while (TRUE)
  50. {
  51. //
  52. // Empty message queue before calling MsgWaitForMultipleObjects or any
  53. // existing messages will not be processed until a new message arrives
  54. // in the queue.
  55. //
  56. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  57. {
  58. switch (msg.message)
  59. {
  60. case WM_QUIT:
  61. case WM_CLOSE:
  62. case WM_DESTROY:
  63. {
  64. // if the message is one that indicates we're trying to close down, we'll signal the abort
  65. // and leave.
  66. dwWaitResult = ERROR_REQUEST_ABORTED;
  67. return dwWaitResult;
  68. }
  69. default:
  70. break;
  71. }
  72. TranslateMessage(&msg);
  73. DispatchMessage(&msg);
  74. }
  75. dwWaitResult = MsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwLoopMS, dwWakeMask);
  76. if (dwWaitResult <= WAIT_OBJECT_0 + nCount - 1)
  77. {
  78. //
  79. // One (or all depending on fWaitAll) of the objects is signaled, return dwWaitResult
  80. //
  81. break;
  82. }
  83. //
  84. // NOTE: we ignore WAIT_ABANDONED_0 + n cases and just time out since our callers
  85. // don't handle this special case.
  86. //
  87. //
  88. // Stop pumping messages after dwMilliseconds
  89. //
  90. // Timer wraparound handled by unsigned subtract
  91. //
  92. if (GetTickCount() - dwTickStart >= dwMilliseconds)
  93. {
  94. //
  95. // No need to continue, even if caused by new message (WAIT_OBJECT_0 + nCount == dwWaitResult),
  96. // we have reached our dwMilliseconds timeout
  97. //
  98. dwWaitResult = WAIT_TIMEOUT;
  99. break;
  100. }
  101. //
  102. // Otherwise continue, WAIT_TIMEOUT from MsgWaitForMultipleObjects is only case left
  103. //
  104. continue;
  105. }
  106. return dwWaitResult;
  107. }