AuroraRuntime/Source/IO/Loop/WaitSingle.Unix.cpp

166 lines
3.7 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: WaitSingle.Unix.cpp
Date: 2022-4-4
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "WaitSingle.hpp"
#include <Source/Time/Time.hpp>
#if defined(AURORA_IS_LINUX_DERIVED)
#include <Source/IO/UNIX/IOSubmit.Linux.hpp>
#endif
namespace Aurora::IO::Loop
{
bool WaitSingleGeneric::WaitForAtleastOne(AuUInt32 timeout, const AuList<AuUInt> &handles, const AuList<AuUInt> &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;
}
if (active == 0)
{
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 == 0)
{
return false;
}
if (active == -1)
{
// todo push error
return false;
}
return active == 1;
}
void WaitSingleGeneric::OnPresleep()
{
}
void WaitSingleGeneric::OnFinishSleep()
{
}
ELoopSource WaitSingleGeneric::GetType()
{
return ELoopSource::eSourceInternalReserved1;
}
}