diff options
Diffstat (limited to 'zenutil/zenserverprocess.cpp')
| -rw-r--r-- | zenutil/zenserverprocess.cpp | 147 |
1 files changed, 102 insertions, 45 deletions
diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 7f4be2368..55b592ab1 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -1,11 +1,12 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include "zenserverprocess.h" +#include "zenutil/zenserverprocess.h" #include <zencore/except.h> #include <zencore/filesystem.h> #include <zencore/fmtutils.h> #include <zencore/logging.h> +#include <zencore/session.h> #include <zencore/string.h> #include <atlbase.h> @@ -16,44 +17,42 @@ ////////////////////////////////////////////////////////////////////////// +namespace zen { + namespace zenutil { -class SecurityAttributes -{ -public: - inline SECURITY_ATTRIBUTES* Attributes() { return &m_Attributes; } + class SecurityAttributes + { + public: + inline SECURITY_ATTRIBUTES* Attributes() { return &m_Attributes; } -protected: - SECURITY_ATTRIBUTES m_Attributes{}; - SECURITY_DESCRIPTOR m_Sd{}; -}; + protected: + SECURITY_ATTRIBUTES m_Attributes{}; + SECURITY_DESCRIPTOR m_Sd{}; + }; -// Security attributes which allows any user access + // Security attributes which allows any user access -class AnyUserSecurityAttributes : public SecurityAttributes -{ -public: - AnyUserSecurityAttributes() + class AnyUserSecurityAttributes : public SecurityAttributes { - m_Attributes.nLength = sizeof m_Attributes; - m_Attributes.bInheritHandle = false; // Disable inheritance - - const BOOL success = InitializeSecurityDescriptor(&m_Sd, SECURITY_DESCRIPTOR_REVISION); - - if (success) + public: + AnyUserSecurityAttributes() { - const BOOL bSetOk = SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE); + m_Attributes.nLength = sizeof m_Attributes; + m_Attributes.bInheritHandle = false; // Disable inheritance - if (bSetOk) + const BOOL Success = InitializeSecurityDescriptor(&m_Sd, SECURITY_DESCRIPTOR_REVISION); + + if (Success) { + if (!SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE)) + { + ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); + } + m_Attributes.lpSecurityDescriptor = &m_Sd; } - else - { - zen::ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); - } } - } -}; + }; } // namespace zenutil @@ -109,7 +108,7 @@ ZenServerState::Initialize() if (hMap == NULL) { - zen::ThrowLastError("Could not open or create file mapping object for Zen server state"); + ThrowLastError("Could not open or create file mapping object for Zen server state"); } m_hMapFile = hMap; @@ -123,10 +122,11 @@ ZenServerState::Initialize() if (pBuf == NULL) { - zen::ThrowLastError("Could not map view of Zen server state"); + ThrowLastError("Could not map view of Zen server state"); } - m_Data = reinterpret_cast<ZenServerEntry*>(pBuf); + m_Data = reinterpret_cast<ZenServerEntry*>(pBuf); + m_IsReadOnly = false; } bool @@ -149,7 +149,7 @@ ZenServerState::InitializeReadOnly() if (pBuf == NULL) { - zen::ThrowLastError("Could not map view of Zen server state"); + ThrowLastError("Could not map view of Zen server state"); } m_Data = reinterpret_cast<ZenServerEntry*>(pBuf); @@ -181,7 +181,7 @@ ZenServerState::Register(int ListenPort) // Allocate an entry - int Pid = zen::GetCurrentProcessId(); + int Pid = GetCurrentProcessId(); for (int i = 0; i < m_MaxEntryCount; ++i) { @@ -199,6 +199,9 @@ ZenServerState::Register(int ListenPort) Entry.Pid = Pid; Entry.Flags = 0; + const Oid SesId = GetSessionId(); + memcpy(Entry.SessionId, &SesId, sizeof SesId); + return &Entry; } } @@ -215,13 +218,15 @@ ZenServerState::Sweep() return; } + ZEN_ASSERT(m_IsReadOnly == false); + for (int i = 0; i < m_MaxEntryCount; ++i) { ZenServerEntry& Entry = m_Data[i]; if (Entry.ListenPort) { - if (zen::IsProcessRunning(Entry.Pid) == false) + if (IsProcessRunning(Entry.Pid) == false) { ZEN_DEBUG("Sweep - pid {} not running, reclaiming entry (port {})", Entry.Pid, Entry.ListenPort); @@ -264,6 +269,30 @@ ZenServerState::ZenServerEntry::SignalShutdownRequest() Flags |= uint16_t(FlagsEnum::kShutdownPlease); } +bool +ZenServerState::ZenServerEntry::AddSponsorProcess(uint32_t PidToAdd) +{ + for (std::atomic<uint32_t>& PidEntry : SponsorPids) + { + if (PidEntry.load(std::memory_order::memory_order_relaxed) == 0) + { + uint32_t Expected = 0; + if (PidEntry.compare_exchange_strong(Expected, uint16_t(PidToAdd))) + { + // Success! + return true; + } + } + else if (PidEntry.load(std::memory_order::memory_order_relaxed) == PidToAdd) + { + // Success, the because pid is already in the list + return true; + } + } + + return false; +} + ////////////////////////////////////////////////////////////////////////// std::atomic<int> TestCounter{0}; @@ -294,7 +323,7 @@ ZenServerEnvironment::InitializeForTest(std::filesystem::path ProgramBaseDir, st ZEN_INFO("Program base dir is '{}'", ProgramBaseDir); ZEN_INFO("Cleaning test base dir '{}'", TestBaseDir); - zen::DeleteDirectories(TestBaseDir.c_str()); + DeleteDirectories(TestBaseDir.c_str()); m_IsTestInstance = true; m_IsInitialized = true; @@ -305,14 +334,14 @@ ZenServerEnvironment::CreateNewTestDir() { using namespace std::literals; - zen::ExtendableWideStringBuilder<256> TestDir; + ExtendableWideStringBuilder<256> TestDir; TestDir << "test"sv << int64_t(++TestCounter); std::filesystem::path TestPath = m_TestBaseDir / TestDir.c_str(); ZEN_INFO("Creating new test dir @ '{}'", TestPath); - zen::CreateDirectories(TestPath.c_str()); + CreateDirectories(TestPath.c_str()); return TestPath; } @@ -377,16 +406,16 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr const int MyPid = _getpid(); const int ChildId = ++ChildIdCounter; - zen::ExtendableStringBuilder<32> ChildEventName; + ExtendableStringBuilder<32> ChildEventName; ChildEventName << "Zen_Child_" << ChildId; - zen::NamedEvent ChildEvent{ChildEventName}; + NamedEvent ChildEvent{ChildEventName}; CreateShutdownEvent(BasePort); - zen::ExtendableStringBuilder<32> LogId; + ExtendableStringBuilder<32> LogId; LogId << "Zen" << ChildId; - zen::ExtendableWideStringBuilder<512> CommandLine; + ExtendableWideStringBuilder<512> CommandLine; CommandLine << "\""; CommandLine.Append(Executable.c_str()); CommandLine << "\""; @@ -395,7 +424,17 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr if (IsTest) { - CommandLine << " --test --owner-pid " << MyPid << " --log-id " << LogId; + if (!m_OwnerPid.has_value()) + { + m_OwnerPid = MyPid; + } + + CommandLine << " --test --log-id " << LogId; + } + + if (m_OwnerPid.has_value()) + { + CommandLine << " --owner-pid " << m_OwnerPid.value(); } CommandLine << " --child-id " << ChildEventName; @@ -515,10 +554,10 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr void ZenServerInstance::CreateShutdownEvent(int BasePort) { - zen::ExtendableStringBuilder<32> ChildShutdownEventName; + ExtendableStringBuilder<32> ChildShutdownEventName; ChildShutdownEventName << "Zen_" << BasePort; ChildShutdownEventName << "_Shutdown"; - zen::NamedEvent ChildShutdownEvent{ChildShutdownEventName}; + NamedEvent ChildShutdownEvent{ChildShutdownEventName}; m_ShutdownEvent = std::move(ChildShutdownEvent); } @@ -554,9 +593,25 @@ ZenServerInstance::AttachToRunningServer(int BasePort) } void +ZenServerInstance::Detach() +{ + if (m_Process.IsValid()) + { + m_Process.Reset(); + m_ShutdownEvent.Close(); + } +} + +void ZenServerInstance::WaitUntilReady() { - m_ReadyEvent.Wait(); + while (m_ReadyEvent.Wait(100) == false) + { + if (!m_Process.IsRunning() || !m_Process.IsValid()) + { + return; + } + } } bool @@ -574,3 +629,5 @@ ZenServerInstance::GetBaseUri() const return "http://localhost:{}"_format(m_BasePort); } + +} // namespace zen |