diff options
| author | Martin Ridgers <[email protected]> | 2021-11-23 11:38:57 +0100 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-11-24 15:56:26 +0100 |
| commit | 3d0257c427712bb0f8f69513ffdd50d15b28ad37 (patch) | |
| tree | bb30cf9307a49ebf151f0e0b537479bda99522d9 /zencore/thread.cpp | |
| parent | Reimplemented NamedEvent on Linux using POSIX message queues (diff) | |
| download | zen-3d0257c427712bb0f8f69513ffdd50d15b28ad37.tar.xz zen-3d0257c427712bb0f8f69513ffdd50d15b28ad37.zip | |
Tests for NamedEvent
Diffstat (limited to 'zencore/thread.cpp')
| -rw-r--r-- | zencore/thread.cpp | 89 |
1 files changed, 87 insertions, 2 deletions
diff --git a/zencore/thread.cpp b/zencore/thread.cpp index 68c5cb3e1..91597b07a 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -24,6 +24,8 @@ # include <unistd.h> #endif +#include <thread> + ZEN_THIRD_PARTY_INCLUDES_START #include <fmt/format.h> ZEN_THIRD_PARTY_INCLUDES_END @@ -591,6 +593,47 @@ ProcessHandle::Wait(int TimeoutMs) ////////////////////////////////////////////////////////////////////////// +static void BuildArgV(std::vector<char*>& Out, char* CommandLine) +{ + char* Cursor = CommandLine; + while (true) + { + // Skip leading whitespace + for (; *Cursor == ' '; ++Cursor); + + // Check for nullp terminator + if (*Cursor == '\0') + { + break; + } + + Out.push_back(Cursor); + + // Extract word + int QuoteCount = 0; + do + { + QuoteCount += (*Cursor == '\"'); + if (*Cursor == ' ' && !(QuoteCount & 1)) + { + break; + } + ++Cursor; + } + while (*Cursor != '\0'); + + if (*Cursor == '\0') + { + break; + } + + *Cursor = '\0'; + ++Cursor; + } + + Out.push_back(nullptr); +} + #if ZEN_PLATFORM_WINDOWS static CreateProcResult CreateProcNormal( const std::filesystem::path& Executable, @@ -780,6 +823,10 @@ CreateProcResult CreateProc( return CreateProcNormal(Executable, CommandLine, Options); #else + std::vector<char*> ArgV; + std::string CommandLineZ(CommandLine); + BuildArgV(ArgV, CommandLineZ.data()); + int ChildPid = fork(); if (ChildPid < 0) { @@ -792,8 +839,7 @@ CreateProcResult CreateProc( chdir(Options.WorkingDirectory->c_str()); } - std::string CommandLineZ(CommandLine); - if (execl(Executable.c_str(), CommandLineZ.c_str(), nullptr) < 0) + if (execv(Executable.c_str(), ArgV.data()) < 0) { ThrowLastError("Failed to exec() a new process image"); } @@ -970,6 +1016,45 @@ TEST_CASE("Thread") CHECK(IsProcessRunning(Pid)); } +TEST_CASE("ipc") +{ + using namespace fmt::literals; + + std::string Name = "zencore_test_event_{}"_format(GetCurrentProcessId()); + NamedEvent TestEvent(Name); + + // Timeout test + for (uint32_t i = 0; i < 8; ++i) + { + bool bEventSet = TestEvent.Wait(100); + CHECK(!bEventSet); + } + + // Thread check + std::thread Waiter = std::thread([Name] () { + NamedEvent ReadyEvent(Name + "_ready"); + ReadyEvent.Set(); + + NamedEvent TestEvent(Name); + TestEvent.Wait(1000); + }); + + NamedEvent ReadyEvent(Name + "_ready"); + ReadyEvent.Wait(); + + zen::Sleep(500); + TestEvent.Set(); + + Waiter.join(); + + // Manual reset property + for (uint32_t i = 0; i < 8; ++i) + { + bool bEventSet = TestEvent.Wait(100); + CHECK(bEventSet); + } +} + #endif // ZEN_WITH_TESTS } // namespace zen |