WindowsHelpers.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "il2cpp-config.h"
  2. #include "WindowsHelpers.h"
  3. #include "os/Time.h"
  4. #if IL2CPP_TARGET_WINDOWS
  5. namespace il2cpp
  6. {
  7. namespace os
  8. {
  9. namespace win
  10. {
  11. WaitStatus WaitForSingleObjectAndAccountForAPCs(HANDLE handle, uint32_t ms, bool interruptible)
  12. {
  13. uint32_t remainingWaitTimeMS = ms;
  14. while (true)
  15. {
  16. uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic();
  17. DWORD result = ::WaitForSingleObjectEx(handle, remainingWaitTimeMS, interruptible);
  18. if (result == WAIT_OBJECT_0)
  19. return kWaitStatusSuccess;
  20. if (result == WAIT_TIMEOUT)
  21. return kWaitStatusTimeout;
  22. if (result == WAIT_IO_COMPLETION)
  23. {
  24. if (ms != INFINITE)
  25. {
  26. uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime;
  27. if (haveWaitedTimeMS >= remainingWaitTimeMS)
  28. return kWaitStatusTimeout;
  29. remainingWaitTimeMS -= haveWaitedTimeMS;
  30. }
  31. continue;
  32. }
  33. break;
  34. }
  35. return kWaitStatusFailure;
  36. }
  37. int32_t WaitForAnyObjectAndAccountForAPCs(const std::vector<HANDLE>& handles, uint32_t ms, bool interruptible)
  38. {
  39. IL2CPP_ASSERT(handles.size() != 0);
  40. uint32_t remainingWaitTimeMS = ms;
  41. while (true)
  42. {
  43. uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic();
  44. DWORD result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), handles.data(), false, remainingWaitTimeMS, interruptible);
  45. // If we are waiting for just one of many objects, the return value
  46. // might be WAIT_OBJECT_0 + the index of the handle that was signaled.
  47. // Check for a return value in that range and return the index of that handle.
  48. if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size())
  49. return result - WAIT_OBJECT_0;
  50. if (result == WAIT_TIMEOUT)
  51. return WAIT_TIMEOUT;
  52. if (result == WAIT_IO_COMPLETION)
  53. {
  54. if (ms != INFINITE)
  55. {
  56. uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime;
  57. if (haveWaitedTimeMS >= remainingWaitTimeMS)
  58. return WAIT_TIMEOUT;
  59. remainingWaitTimeMS -= haveWaitedTimeMS;
  60. }
  61. continue;
  62. }
  63. break;
  64. }
  65. return WAIT_FAILED;
  66. }
  67. bool WaitForAllObjectsAndAccountForAPCs(const std::vector<HANDLE>& handles, uint32_t ms, bool interruptible)
  68. {
  69. IL2CPP_ASSERT(handles.size() != 0);
  70. uint32_t remainingWaitTimeMS = ms;
  71. while (true)
  72. {
  73. uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic();
  74. DWORD result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), handles.data(), true, remainingWaitTimeMS, interruptible);
  75. if (result == WAIT_OBJECT_0)
  76. return true;
  77. if (result == WAIT_TIMEOUT)
  78. return false;
  79. if (result == WAIT_IO_COMPLETION)
  80. {
  81. if (ms != INFINITE)
  82. {
  83. uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime;
  84. if (haveWaitedTimeMS >= remainingWaitTimeMS)
  85. return false;
  86. remainingWaitTimeMS -= haveWaitedTimeMS;
  87. }
  88. continue;
  89. }
  90. break;
  91. }
  92. return false;
  93. }
  94. }
  95. }
  96. }
  97. #endif // IL2CPP_TARGET_WINDOWS