/*** 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::IO::Loop { LSSemaphore::LSSemaphore(AuUInt32 initialCount) { Init(initialCount); } LSSemaphore::LSSemaphore(int handle, int tag) { this->handle = handle; } LSSemaphore::~LSSemaphore() { if ((this->handle != 0) && (this->handle != -1)) { ::close(AuExchange(this->handle, -1)); } } void LSSemaphore::Init(AuUInt32 initialCount) { handle = ::eventfd(initialCount, EFD_SEMAPHORE | EFD_NONBLOCK | EFD_CLOEXEC); } 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); } bool LSSemaphore::WaitOn(AuUInt32 timeout) { return LSHandle::WaitOn(timeout); } ELoopSource LSSemaphore::GetType() { return ELoopSource::eSourceSemaphore; } AUKN_SYM AuSPtr NewLSSemaphore(AuUInt32 initialCount) { auto pSemaphore = AuMakeShared(initialCount); if (!pSemaphore) { return {}; } if (!pSemaphore->HasValidHandle()) { return {}; } return pSemaphore; } }