diff options
| author | Stefan Boberg <[email protected]> | 2023-12-11 13:09:03 +0100 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2023-12-11 13:09:03 +0100 |
| commit | 93afeddbc7a5b5df390a29407f5515acd5a70fc1 (patch) | |
| tree | 6f85ee551aabe20dece64a750c0b2d5d2c5d2d5d /src/zenutil/zenserverprocess.cpp | |
| parent | removed unnecessary SHA1 references (diff) | |
| parent | Make sure that PathFromHandle don't hide true error when throwing exceptions ... (diff) | |
| download | zen-93afeddbc7a5b5df390a29407f5515acd5a70fc1.tar.xz zen-93afeddbc7a5b5df390a29407f5515acd5a70fc1.zip | |
Merge branch 'main' of https://github.com/EpicGames/zen
Diffstat (limited to 'src/zenutil/zenserverprocess.cpp')
| -rw-r--r-- | src/zenutil/zenserverprocess.cpp | 152 |
1 files changed, 101 insertions, 51 deletions
diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 83c6668ba..909692fbc 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -12,6 +12,8 @@ #include <atomic> +#include <gsl/gsl-lite.hpp> + #if ZEN_PLATFORM_WINDOWS # include <zencore/windows.h> #else @@ -468,7 +470,14 @@ ZenServerInstance::ZenServerInstance(ZenServerEnvironment& TestEnvironment) : m_ ZenServerInstance::~ZenServerInstance() { - Shutdown(); + try + { + Shutdown(); + } + catch (const std::exception& Err) + { + ZEN_ERROR("Shutting down zenserver instance failed, reason: '{}'", Err.what()); + } } void @@ -480,19 +489,33 @@ ZenServerInstance::SignalShutdown() void ZenServerInstance::Shutdown() { - if (m_Process.IsValid() && m_ShutdownOnDestroy) + if (m_Process.IsValid()) { - if (m_Terminate) + if (m_ShutdownOnDestroy) { - ZEN_INFO("Terminating zenserver process"); - m_Process.Terminate(111); - m_Process.Reset(); + if (m_Terminate) + { + ZEN_INFO("Terminating zenserver process {}", m_Name); + m_Process.Terminate(111); + m_Process.Reset(); + ZEN_DEBUG("zenserver process {} ({}) terminated", m_Name, m_Process.Pid()); + } + else + { + ZEN_DEBUG("Requesting zenserver process {} ({}) to shut down", m_Name, m_Process.Pid()); + SignalShutdown(); + ZEN_DEBUG("Waiting for zenserver process {} ({}) to shut down", m_Name, m_Process.Pid()); + while (!m_Process.Wait(5000)) + { + ZEN_WARN("Waiting for zenserver process {} ({}) timed out", m_Name, m_Process.Pid()); + } + m_Process.Reset(); + } + ZEN_DEBUG("zenserver process {} ({}) exited", m_Name, m_Process.Pid()); } else { - SignalShutdown(); - m_Process.Wait(); - m_Process.Reset(); + ZEN_DEBUG("Detached from zenserver process {} ({})", m_Name, m_Process.Pid()); } } } @@ -509,10 +532,9 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr ChildEventName << "Zen_Child_" << ChildId; NamedEvent ChildEvent{ChildEventName}; - CreateShutdownEvent(BasePort); - ExtendableStringBuilder<32> LogId; LogId << "Zen" << ChildId; + m_Name = LogId.ToString(); ExtendableStringBuilder<512> CommandLine; CommandLine << "zenserver" ZEN_EXE_SUFFIX_LITERAL; // see CreateProc() call for actual binary path @@ -526,7 +548,8 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr m_OwnerPid = MyPid; } - CommandLine << " --test --log-id " << LogId; + CommandLine << " --test --log-id " << m_Name; + CommandLine << " --no-sentry"; } if (m_OwnerPid.has_value()) @@ -544,7 +567,7 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr if (BasePort) { CommandLine << " --port " << BasePort; - m_BasePort = BasePort; + m_BasePort = gsl::narrow_cast<uint16_t>(BasePort); } if (!m_TestDir.empty()) @@ -604,41 +627,8 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr { if (!WaitUntilReady(WaitTimeoutMs)) { - throw std::runtime_error(fmt::format("server start timeout after {}", NiceTimeSpanMs(WaitTimeoutMs))); + throw std::runtime_error(fmt::format("server start of {} timeout after {}", m_Name, NiceTimeSpanMs(WaitTimeoutMs))); } - - // Determine effective base port - - ZenServerState State; - if (!State.InitializeReadOnly()) - { - // TODO: return success/error code instead? - throw std::runtime_error("no zen state found"); - } - - const ZenServerState::ZenServerEntry* Entry = nullptr; - - if (BasePort) - { - Entry = State.Lookup(BasePort); - } - else - { - State.Snapshot([&](const ZenServerState::ZenServerEntry& InEntry) { - if (InEntry.Pid == static_cast<uint32_t>(GetProcessId(ChildPid))) - { - Entry = &InEntry; - } - }); - } - - if (!Entry) - { - // TODO: return success/error code instead? - throw std::runtime_error("no server entry found"); - } - - m_BasePort = Entry->EffectiveListenPort; } } @@ -694,23 +684,73 @@ ZenServerInstance::Detach() } } -void +uint16_t ZenServerInstance::WaitUntilReady() { while (m_ReadyEvent.Wait(100) == false) { if (!m_Process.IsRunning() || !m_Process.IsValid()) { - ZEN_INFO("Wait abandoned by invalid process (running={})", m_Process.IsRunning()); - return; + ZEN_WARN("Wait abandoned by invalid process (running={})", m_Process.IsRunning()); + + return 0; } } + + OnServerReady(); + + return m_BasePort; } bool ZenServerInstance::WaitUntilReady(int Timeout) { - return m_ReadyEvent.Wait(Timeout); + if (m_ReadyEvent.Wait(Timeout)) + { + OnServerReady(); + + return true; + } + + return false; +} + +void +ZenServerInstance::OnServerReady() +{ + // Determine effective base port + + ZenServerState State; + if (!State.InitializeReadOnly()) + { + // TODO: return success/error code instead? + throw std::runtime_error("no zen state found"); + } + + const ZenServerState::ZenServerEntry* Entry = nullptr; + + if (m_BasePort) + { + Entry = State.Lookup(m_BasePort); + } + else + { + State.Snapshot([&](const ZenServerState::ZenServerEntry& InEntry) { + if (InEntry.Pid == (uint32_t)m_Process.Pid()) + { + Entry = &InEntry; + } + }); + } + + if (!Entry) + { + // TODO: return success/error code instead? + throw std::runtime_error("no server entry found"); + } + + m_BasePort = Entry->EffectiveListenPort; + CreateShutdownEvent(m_BasePort); } std::string @@ -728,4 +768,14 @@ ZenServerInstance::SetTestDir(std::filesystem::path TestDir) m_TestDir = TestDir; } +bool +ZenServerInstance::IsRunning() +{ + if (!m_Process.IsValid()) + { + return false; + } + return m_Process.IsRunning(); +} + } // namespace zen |