#include "il2cpp-config.h" #include "WindowsHelpers.h" #include "os/Time.h" #if IL2CPP_TARGET_WINDOWS namespace il2cpp { namespace os { namespace win { WaitStatus WaitForSingleObjectAndAccountForAPCs(HANDLE handle, uint32_t ms, bool interruptible) { uint32_t remainingWaitTimeMS = ms; while (true) { uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic(); DWORD result = ::WaitForSingleObjectEx(handle, remainingWaitTimeMS, interruptible); if (result == WAIT_OBJECT_0) return kWaitStatusSuccess; if (result == WAIT_TIMEOUT) return kWaitStatusTimeout; if (result == WAIT_IO_COMPLETION) { if (ms != INFINITE) { uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime; if (haveWaitedTimeMS >= remainingWaitTimeMS) return kWaitStatusTimeout; remainingWaitTimeMS -= haveWaitedTimeMS; } continue; } break; } return kWaitStatusFailure; } int32_t WaitForAnyObjectAndAccountForAPCs(const std::vector& handles, uint32_t ms, bool interruptible) { IL2CPP_ASSERT(handles.size() != 0); uint32_t remainingWaitTimeMS = ms; while (true) { uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic(); DWORD result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), handles.data(), false, remainingWaitTimeMS, interruptible); // If we are waiting for just one of many objects, the return value // might be WAIT_OBJECT_0 + the index of the handle that was signaled. // Check for a return value in that range and return the index of that handle. if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size()) return result - WAIT_OBJECT_0; if (result == WAIT_TIMEOUT) return WAIT_TIMEOUT; if (result == WAIT_IO_COMPLETION) { if (ms != INFINITE) { uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime; if (haveWaitedTimeMS >= remainingWaitTimeMS) return WAIT_TIMEOUT; remainingWaitTimeMS -= haveWaitedTimeMS; } continue; } break; } return WAIT_FAILED; } bool WaitForAllObjectsAndAccountForAPCs(const std::vector& handles, uint32_t ms, bool interruptible) { IL2CPP_ASSERT(handles.size() != 0); uint32_t remainingWaitTimeMS = ms; while (true) { uint32_t waitStartTime = os::Time::GetTicksMillisecondsMonotonic(); DWORD result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), handles.data(), true, remainingWaitTimeMS, interruptible); if (result == WAIT_OBJECT_0) return true; if (result == WAIT_TIMEOUT) return false; if (result == WAIT_IO_COMPLETION) { if (ms != INFINITE) { uint32_t haveWaitedTimeMS = os::Time::GetTicksMillisecondsMonotonic() - waitStartTime; if (haveWaitedTimeMS >= remainingWaitTimeMS) return false; remainingWaitTimeMS -= haveWaitedTimeMS; } continue; } break; } return false; } } } } #endif // IL2CPP_TARGET_WINDOWS