WaitFor.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Version : 2.3.15
  5. * Author : Bruce Liang
  6. * Website : http://www.jessma.org
  7. * Project : https://github.com/ldcsaa
  8. * Blog : http://www.cnblogs.com/ldcsaa
  9. * Wiki : http://www.oschina.net/p/hp-socket
  10. * QQ Group : 75375912
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. #include "stdafx.h"
  25. #include "WaitFor.h"
  26. #include "GeneralHelper.h"
  27. #include "CriticalSection.h"
  28. #include <MmSystem.h>
  29. #pragma comment(lib, "Winmm")
  30. DWORD TimeGetTime()
  31. {
  32. return ::timeGetTime();
  33. }
  34. DWORD GetTimeGap32(DWORD dwOriginal)
  35. {
  36. return ::timeGetTime() - dwOriginal;
  37. }
  38. #if _WIN32_WINNT >= _WIN32_WINNT_WS08
  39. ULONGLONG GetTimeGap64(ULONGLONG ullOriginal)
  40. {
  41. return ::GetTickCount64() - ullOriginal;
  42. }
  43. #endif
  44. BOOL PeekMessageLoop(BOOL bDispatchQuitMsg)
  45. {
  46. BOOL value = TRUE;
  47. MSG msg;
  48. while(::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
  49. {
  50. if(msg.message == WM_QUIT && !bDispatchQuitMsg)
  51. {
  52. value = FALSE;
  53. break;
  54. }
  55. ::TranslateMessage(&msg);
  56. ::DispatchMessage(&msg);
  57. }
  58. return value;
  59. }
  60. DWORD WaitForMultipleObjectsWithMessageLoop(DWORD dwHandles, HANDLE szHandles[], DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags)
  61. {
  62. DWORD dwResult = WAIT_FAILED;
  63. DWORD dwBeginTime = (dwMilliseconds == INFINITE) ? INFINITE : ::timeGetTime();
  64. while(TRUE)
  65. {
  66. int iWaitTime;
  67. if(dwBeginTime != INFINITE)
  68. {
  69. iWaitTime = dwMilliseconds - (GetTimeGap32(dwBeginTime));
  70. if(iWaitTime <= 0)
  71. {
  72. dwResult = WAIT_TIMEOUT;
  73. break;
  74. }
  75. }
  76. else
  77. iWaitTime = INFINITE;
  78. dwResult = ::MsgWaitForMultipleObjectsEx(dwHandles, szHandles, iWaitTime, dwWakeMask, dwFlags);
  79. ASSERT(dwResult != WAIT_FAILED);
  80. if(dwResult == (WAIT_OBJECT_0 + dwHandles))
  81. PeekMessageLoop();
  82. else
  83. break;
  84. }
  85. return dwResult;
  86. }
  87. BOOL MsgWaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags)
  88. {
  89. DWORD dwResult = WaitForMultipleObjectsWithMessageLoop(1, &hHandle, dwMilliseconds, dwWakeMask, dwFlags);
  90. switch(dwResult)
  91. {
  92. case WAIT_OBJECT_0:
  93. return TRUE;
  94. case WAIT_FAILED:
  95. ASSERT(FALSE);
  96. case WAIT_TIMEOUT:
  97. return FALSE;
  98. default:
  99. ASSERT(FALSE);
  100. }
  101. return FALSE;
  102. }
  103. void WaitWithMessageLoop(DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags)
  104. {
  105. static CEvt evWait;
  106. VERIFY(MsgWaitForSingleObject(evWait, dwMilliseconds, dwWakeMask, dwFlags) == FALSE);
  107. }
  108. void WaitForWorkingQueue(long* plWorkingItemCount, long lMaxWorkingItemCount, DWORD dwCheckInterval)
  109. {
  110. while(*plWorkingItemCount > lMaxWorkingItemCount)
  111. ::Sleep(dwCheckInterval);
  112. }
  113. void WaitForComplete(long* plWorkingItemCount, DWORD dwCheckInterval)
  114. {
  115. WaitForWorkingQueue(plWorkingItemCount, 0, dwCheckInterval);
  116. }
  117. void MsgWaitForWorkingQueue(long* plWorkingItemCount, long lMaxWorkingItemCount, DWORD dwCheckInterval)
  118. {
  119. while(*plWorkingItemCount > lMaxWorkingItemCount)
  120. WaitWithMessageLoop(dwCheckInterval);
  121. }
  122. void MsgWaitForComplete(long* plWorkingItemCount, DWORD dwCheckInterval)
  123. {
  124. MsgWaitForWorkingQueue(plWorkingItemCount, 0, dwCheckInterval);
  125. }