/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: WaitSingle.Unix.cpp Date: 2022-4-4 Author: Reece ***/ #include #include "WaitSingle.hpp" #include #if defined(AURORA_IS_LINUX_DERIVED) #include #endif namespace Aurora::Loop { bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList &handles, const AuList &handlesWrite, AuUInt &one, AuUInt &two) { fd_set readSet, writeSet; AuUInt maxHandle {}; struct timeval tv {}; // TODO: IO SUBMIT HOOK FD_ZERO(&readSet); FD_ZERO(&writeSet); if (timeout) { AuTime::ms2tv(&tv, timeout); } for (const auto i : handles) { if (i == -1) continue; FD_SET(i, &readSet); maxHandle = AuMax(maxHandle, i + 1); } for (const auto i : handlesWrite) { if (i == -1) continue; FD_SET(i, &writeSet); maxHandle = AuMax(maxHandle, i + 1); } auto active = select(maxHandle, handles.size() ? &readSet : nullptr, handlesWrite.size() ? &writeSet : nullptr, nullptr, timeout == AuUInt32(-1) ? nullptr : &tv); if (active == -1) { // todo push error return false; } for (const auto i : handles) { if (!FD_ISSET(i, &readSet)) { continue; } one = i; break; } for (const auto i : handlesWrite) { if (!FD_ISSET(i, &writeSet)) { continue; } two = i; break; } return true; } bool WaitSingleGeneric::WaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write) { fd_set readSet, writeSet; struct timeval tv {}; int maxFd {}; #if defined(AURORA_IS_LINUX_DERIVED) { bool bWriteTriggered, bReadTriggered; if (IO::UNIX::LinuxOverlappedWaitForOne(timeout, read, write, bReadTriggered, bWriteTriggered)) { if (!bWriteTriggered && !bReadTriggered) { return false; } return true; } } #endif FD_ZERO(&readSet); FD_ZERO(&writeSet); if (timeout) { AuTime::ms2tv(&tv, timeout); } if (read != -1) { maxFd = read + 1; FD_SET(read, &readSet); } if (write != -1) { FD_SET(write, &writeSet); maxFd = AuMax(maxFd, int(write) + 1); } auto active = select(maxFd, read != -1 ? &readSet : nullptr, write != -1 ? &writeSet : nullptr, nullptr, timeout == AuUInt32(-1) ? nullptr : &tv); if (active == -1) { // todo push error return false; } return active == 1; } void WaitSingleGeneric::OnPresleep() { } void WaitSingleGeneric::OnFinishSleep() { } ELoopSource WaitSingleGeneric::GetType() { return ELoopSource::eSourceInternalReserved1; } }