/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AsyncApp.cpp Date: 2021-6-26 Author: Reece ***/ #include #include "Async.hpp" #include "AsyncApp.hpp" #include "WorkItem.hpp" #include "Schedular.hpp" #include namespace Aurora::Async { static AsyncApp *gAsyncApp; static AuSPtr gAsyncAppMem; void InitApp() { gAsyncAppMem = AuMakeShared(); gAsyncApp = gAsyncAppMem.get(); } void ReleaseApp() { gAsyncAppMem.reset(); } void AsyncApp::Start() { ThreadPool::SetRunningMode(true); SysAssert(ThreadPool::Create({0, 0})); StartSched(); // this is now an init once function } void AsyncApp::Main() { ThreadPool::Entrypoint({0, 0}); } void AsyncApp::SetConsoleCommandDispatcher(WorkerId_t id) { commandDispatcher_ = id; Console::Commands::UpdateDispatcher(commandDispatcher_); } void AsyncApp::CleanUpWorker(WorkerId_t id) { // This shouldn't be a problem; however, we're going to handle the one edge case where // some angry sysadmin is spamming commands if ((commandDispatcher_.has_value()) && (commandDispatcher_.value() == id)) { Console::Commands::UpdateDispatcher({}); } } void AsyncApp::CleanWorkerPoolReservedZeroFree() { // TODO: this is a hack. we need to reference count DeinitSched(); ThreadPool::Shutdown(); } AUKN_SYM IAsyncApp *GetAsyncApp() { return gAsyncApp; } bool AsyncApp::Spawn(WorkerId_t workerId) { return ThreadPool::Spawn(workerId); } void AsyncApp::SetRunningMode(bool eventRunning) { ThreadPool::SetRunningMode(eventRunning); } bool AsyncApp::Create(WorkerId_t workerId) { return ThreadPool::Create(workerId); } bool AsyncApp::InRunnerMode() { return ThreadPool::InRunnerMode(); } bool AsyncApp::Poll() { return ThreadPool::Poll(); } bool AsyncApp::RunOnce() { return ThreadPool::RunOnce(); } bool AsyncApp::Run() { return ThreadPool::Run(); } void AsyncApp::Shutdown() { ThreadPool::Shutdown(); } bool AsyncApp::Exiting() { return ThreadPool::Exiting(); } AuSPtr AsyncApp::NewWorkItem(const WorkerId_t &worker, const AuSPtr &task, bool supportsBlocking) { return ThreadPool::NewWorkItem(worker, task, supportsBlocking); } AuSPtr AsyncApp::NewFence() { return ThreadPool::NewFence(); } Threading::Threads::ThreadShared_t AsyncApp::ResolveHandle(WorkerId_t id) { return ThreadPool::ResolveHandle(id); } AuBST> AsyncApp::GetThreads() { return ThreadPool::GetThreads(); } WorkerId_t AsyncApp::GetCurrentThread() { return ThreadPool::GetCurrentThread(); } bool AsyncApp::Sync(WorkerId_t workerId, AuUInt32 timeoutMs, bool requireSignal) { return ThreadPool::Sync(workerId, timeoutMs, requireSignal); } AuSPtr AsyncApp::WorkerToLoopSource(WorkerId_t id) { return ThreadPool::WorkerToLoopSource(id); } void AsyncApp::Signal(WorkerId_t workerId) { ThreadPool::Signal(workerId); } void AsyncApp::SyncAllSafe() { ThreadPool::SyncAllSafe(); } void AsyncApp::AddFeature(WorkerId_t id, AuSPtr feature, bool async) { ThreadPool::AddFeature(id, feature, async); } void AsyncApp::AssertInThreadGroup(ThreadGroup_t group) { ThreadPool::AssertInThreadGroup(group); } void AsyncApp::AssertWorker(WorkerId_t id) { ThreadPool::AssertWorker(id); } bool AsyncApp::ScheduleLoopSource(const AuSPtr &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer, bool> &callback) { return ThreadPool::ScheduleLoopSource(loopSource, workerId, timeout, callback); } }