/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: LSSemaphore.Linux.cpp Date: 2022-4-5 Author: Reece ***/ #include #include "LSSemaphore.hpp" #include "LSFromFdNonblocking.hpp" namespace Aurora::Loop { LSSemaphore::LSSemaphore(AuUInt32 initialCount) { Init(initialCount); } void LSSemaphore::Init(AuUInt32 initialCount) { handle = eventfd(initialCount, EFD_SEMAPHORE | EFD_NONBLOCK); } bool LSSemaphore::IsSignaledNonblocking() { AuUInt64 oldSemaphoreValue {}; return read(this->handle, &oldSemaphoreValue, sizeof(oldSemaphoreValue)) == 8; } bool LSSemaphore::AddOne() { AuUInt64 plsNoOverflow {1}; if (write(this->handle, &plsNoOverflow, sizeof(plsNoOverflow)) != 8) { // todo push error return false; } return true; } bool LSSemaphore::OnTrigger(AuUInt handle) { return IsSignaledNonblocking(); } bool LSSemaphore::IsSignaled() { return IsSignaledFromNonblockingImpl(this, this, &LSSemaphore::IsSignaledNonblocking); } ELoopSource LSSemaphore::GetType() { return ELoopSource::eSourceSemaphore; } AUKN_SYM AuSPtr NewLSSemaphore(AuUInt32 initialCount) { auto semaphore = AuMakeShared(initialCount); if (!semaphore) { return {}; } if (!semaphore->HasValidHandle()) { return {}; } return semaphore; } }