diff --git a/Aurora/Runtime b/Aurora/Runtime index 45975e4..61f20b6 160000 --- a/Aurora/Runtime +++ b/Aurora/Runtime @@ -1 +1 @@ -Subproject commit 45975e475571bf76dace0aab9bd30b263eec0192 +Subproject commit 61f20b6c697f498db6f2b46e89830ce6ea09322d diff --git a/Tests/Public/11. Hello Processes/Main.cpp b/Tests/Public/11. Hello Processes/Main.cpp index 69ede2d..7c57630 100644 --- a/Tests/Public/11. Hello Processes/Main.cpp +++ b/Tests/Public/11. Hello Processes/Main.cpp @@ -38,6 +38,82 @@ TEST(Process, RunSystem) AuLogDbg("Exit Code: 0x{:x}", (AuUInt)process->GetExitCode()); } +TEST(Process, RunSystemLoopSourceStdOut) +{ + auto proc = "^/HelloSystem" + #if defined(AURORA_PLATFORM_WIN32) + ".exe" + #endif + ; + + AuProcesses::StartupParmaters params; + params.type = AuProcesses::ESpawnType::eSpawnChildProcessWorker; + params.process = proc; + params.fwdOut = true; + params.fwdIn = true; + params.noShowConsole = true; + auto process = AuProcesses::SpawnUnique(params); + ASSERT_TRUE(static_cast(process)); + + ASSERT_TRUE(process->Start()); + + bool bIsRunning {true}; + AuByteBuffer stdoutPipe(4096 * 16); + AuMemoryViewWrite readView(stdoutPipe.begin(), stdoutPipe.end()); + + auto transaction = process->NewAsyncTransaction(); + auto transactionSource = transaction->NewLoopSource(); + auto processDeadLoopSource = process->AsLoopSource(); + + auto processDeadCallback = AuMakeShared([&](const AuSPtr &source) -> bool + { + AuLogDbg("Exit Code [2]: 0x{:x} -> exiting", (AuUInt)process->GetExitCode()); + bIsRunning = false; + return false; // dont evict + }); + + transaction->SetCallback(AuMakeShared([&](AuUInt64 offset, AuUInt32 length) + { + transaction->Reset(); + + if (length) + { + AuLogDbg("STDOUT {}", AuString(stdoutPipe.begin(), stdoutPipe.begin() + length)); + transaction->StartRead(0, AuUnsafeRaiiToShared(&readView)); // NOTE: removed assert bc the final read +1 may result in an instant nonblocking error under NT + } + })); + + ASSERT_TRUE(transaction->StartRead(0, AuUnsafeRaiiToShared(&readView))); + + auto loop = Aurora::Loop::NewLoopQueue(); + + ASSERT_TRUE(loop->SourceAdd(transactionSource)); + ASSERT_TRUE(loop->SourceAdd(processDeadLoopSource)); + + ASSERT_TRUE(loop->AddCallback(processDeadLoopSource, processDeadCallback)); + + ASSERT_TRUE(loop->Commit()); + + while (bIsRunning) + { + loop->WaitAny(); + } + + // Read until EOF + while (transactionSource->IsSignaled()) + { + } + + // Report any remaining bytes + { + AuByteBuffer stdoutPipe(4096 * 16); + AuUInt written {}; + while (process->Read(AuProcesses::EStandardHandle::eStdOut, AuMemoryViewStreamWrite {stdoutPipe.begin(), stdoutPipe.end(), written}, false)) + { + AuLogDbg("FAIL {}", AuString(stdoutPipe.begin(), stdoutPipe.begin() + written)); + } + } +} void RunTests() { Aurora::RuntimeStartInfo info; diff --git a/Tests/Public/5. Hello Loop/Main.cpp b/Tests/Public/5. Hello Loop/Main.cpp index 8964a21..9abf7d4 100644 --- a/Tests/Public/5. Hello Loop/Main.cpp +++ b/Tests/Public/5. Hello Loop/Main.cpp @@ -155,6 +155,29 @@ TEST(Loop, Timer3) ASSERT_FALSE(loop->WaitAny(100)); } +TEST(Loop, Timer4) +{ + auto timer = AuLoop::NewLSTimer(AuTime::CurrentClockMS() + 100, 100, 2); + + timer->UpdateTimeNs(AuTime::CurrentClockNS() + AuMSToNS(100)); + timer->UpdateTickRateIfAnyNs(AuMSToNS(100), 2); + + // Create loop to sync against the two outstanding IO requests + auto loop = AuLoop::NewLoopQueue(); + + // Add initial loop sources + ASSERT_TRUE(loop->SourceAdd(timer)); + ASSERT_TRUE(loop->Commit()); + + // Test for incremental ticks + ASSERT_FALSE(loop->WaitAll(5)); + ASSERT_TRUE(loop->WaitAll(100)); + ASSERT_FALSE(loop->WaitAll(5)); + ASSERT_TRUE(loop->WaitAll(100)); + ASSERT_FALSE(loop->WaitAll(5)); + ASSERT_FALSE(loop->WaitAll(100)); +} + // // Note: kernel loop queues also support async file and pipe transactions. // See the specialized tests for loop queue related interfaces