/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: LSFromFdNonblocking.cpp Date: 2022-4-5 Author: Reece ***/ #pragma once #if defined(AURORA_IS_LINUX_DERIVED) namespace Aurora::IO::UNIX { bool LinuxOverlappedYield(bool bUserspaceOnly); } #endif namespace Aurora::IO::Loop { extern AuRWRenterableLock gWaitForMultipleALLLock; template inline bool IsSignaledFromNonblockingImpl(ILoopSourceEx *source, T * that, bool(T::*IsSignaledNonblocking)(), bool bIOTick) { bool val {}; source->OnPresleep(); val = ((that)->*(IsSignaledNonblocking))(); source->OnFinishSleep(); #if !defined(AU_NO_WAITMULTIPLELS_ALL_MS_PARITY) if (!val && gRuntimeConfig.ioConfig.bAimCloserForNTParityWaitALL) { AU_LOCK_GLOBAL_GUARD(gWaitForMultipleALLLock->AsReadable()); source->OnPresleep(); val = ((that)->*(IsSignaledNonblocking))(); source->OnFinishSleep(); } #endif // Required for precise Windows on Linux OVERLAPPED semantics for emulators. // IAsyncTransaction::Complete()/Wait() will always enter an alertable state and dispatch io completion callbacks. // In theory, we don't need this. // In practice, if NT can atomically set an event and update the apc queue, we could be out of parity. if (bIOTick) { #if defined(AURORA_IS_LINUX_DERIVED) // Do not syscall after read or select again under Linux UNIX::LinuxOverlappedYield(true); #else IOYield(); #endif } return val; } }