/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IThreadPool.hpp Date: 2021-11-1 Author: Reece ***/ #pragma once namespace Aurora::IO::Loop { struct ILoopQueue; struct ILoopSource; } namespace Aurora::IO::Net { struct INetInterface; struct INetWorker; } namespace Aurora::IO::CompletionGroup { struct ICompletionGroup; } namespace Aurora::Async { struct IThreadPool { // Spawning virtual bool Spawn(WorkerId_t workerId) = 0; // Event runner threads release the thread pool upon encountering a zero work condition, // allowing for a clean exit out of event driven apps, without the headache of carefully // chaining together exit callbacks. // // Applications that aren't designed around an event driven model should set/keep running // mode to false to keep-alive the runners during work exhaustion // // tl'dr: runner = true, async app; runner = false, thread pool virtual void SetRunningMode(bool bRunnerMode) = 0; // Converts the current thread into an async thread // Use with RunOnce, Poll virtual bool Create(WorkerId_t workerId) = 0; //virtual bool CreateAndRun(WorkerId_t workerId) = 0; // @returns any threads with runner = true virtual bool InRunnerMode() = 0; // Manual execution for ::Create() users and those wishing to nest ticks virtual bool Poll() = 0; // Block for one virtual bool RunOnce() = 0; // Block for standard execution virtual bool Run() = 0; // Poll for any counted virtual AuUInt32 PollAndCount(bool bStrict = true) = 0; // Alternative ::Poll that's safer to use with mixed IO // Returns exact amount of AuAsync callbacks dispatched virtual AuUInt32 RunAllPending() = 0; // virtual void Shutdown() = 0; virtual bool Exiting() = 0; // virtual AuSPtr NewWorkItem(const WorkerId_t &worker, const AuSPtr &task) = 0; virtual AuSPtr NewWorkFunction(const WorkerId_t &worker, AuVoidFunc callback) = 0; virtual AuSPtr NewFence() = 0; // virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0; // virtual AuBST> GetThreads() = 0; // virtual WorkerId_t GetCurrentThread() = 0; // virtual AuSPtr GetIOProcessor(WorkerId_t id) = 0; virtual AuSPtr GetIONetInterface(WorkerId_t id) = 0; virtual AuSPtr GetIONetWorker(WorkerId_t id) = 0; virtual AuSPtr GetIOGroup(WorkerId_t id) = 0; // Synchronization // Legacy Barrier: blocks a/a group of threads // Note: syncing to yourself will nullify requireSignal to prevent deadlock conditions virtual bool Sync(WorkerId_t workerId, AuUInt32 timeoutMs = 0, bool bRequireSignal = false) = 0; // Legacy Barrier: wakes up a/a group of ::Sync()'d threads virtual void Signal(WorkerId_t workerId) = 0; // Breaks ::RunOnce() virtual void Wakeup(WorkerId_t workerId) = 0; virtual AuSPtr WorkerToLoopSource(WorkerId_t id) = 0; virtual void SyncAllSafe() = 0; // Features /** * @brief * @param id * @param feature * @param bDontBlockUntilComplete inverse of block until complete. default: block until after IThreadFeature::Init */ virtual void AddFeature(WorkerId_t id, AuSPtr feature, bool bDontBlockUntilComplete = false) = 0; // Debug virtual void AssertInThreadGroup(ThreadGroup_t group) = 0; virtual void AssertWorker(WorkerId_t id) = 0; // AuIO overlapped-IO glue virtual AuSPtr ToKernelWorkQueue() = 0; virtual AuSPtr ToKernelWorkQueue(WorkerId_t workerId) = 0; // virtual AuSPtr GetShutdownEvent() = 0; /** * @brief Prevents preemptive shutdown in ::SetRunningMode(true) mode given loosely held delegation thread pools * @param pPool */ virtual void AddDependency(AuSPtr pPool) = 0; /** * @brief */ virtual void IncrementAbortFenceOnPool() = 0; /** * @brief * @param workerId */ virtual void IncrementAbortFenceOnWorker(WorkerId_t workerId) = 0; /** * @brief * @return */ virtual AuUInt64 QueryAbortFence(AuOptional optWorkerId) = 0; /** * @brief * @param uFenceMagic * @return */ virtual bool QueryShouldAbort(AuOptional optWorkerId, AuUInt64 uFenceMagic) = 0; AURT_ADD_USR_DATA; }; }