From 287f6280fcb32820f2c69def0bdced96d804429b Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Thu, 16 Sep 2021 21:08:47 +0200 Subject: Changed how sponsor processes are managed We can now monitor more than one process and if a new process is started on the same port we will hand over the owner pid to the process which is already executing before exiting. Note that this is only done if there is actually already an owner process in the instance list. --- zenutil/zenserverprocess.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 00f5d4c0d..5142c6a54 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -199,6 +200,9 @@ ZenServerState::Register(int ListenPort) Entry.Pid = Pid; Entry.Flags = 0; + const zen::Oid SesId = zen::GetSessionId(); + memcpy(Entry.SessionId, &SesId, sizeof SesId); + return &Entry; } } @@ -264,6 +268,30 @@ ZenServerState::ZenServerEntry::SignalShutdownRequest() Flags |= uint16_t(FlagsEnum::kShutdownPlease); } +bool +ZenServerState::ZenServerEntry::AddSponsorProcess(uint32_t PidToAdd) +{ + for (std::atomic& 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 TestCounter{0}; @@ -395,7 +423,17 @@ ZenServerInstance::SpawnServer(int BasePort) 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; @@ -548,10 +586,26 @@ ZenServerInstance::AttachToRunningServer(int BasePort) CreateShutdownEvent(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 -- cgit v1.2.3 From 5f4251e36812dc68bff9e59c012c1e2f7aa697f8 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 09:20:07 +0200 Subject: Moved zenserverprocess into zenutil/zenserverprocess.h --- zenutil/zenserverprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 2f2b3bd33..622423cac 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -1,6 +1,6 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include "zenserverprocess.h" +#include "zenutil/zenserverprocess.h" #include #include -- cgit v1.2.3 From 6da25650aa4bf87dcd5e3d612c615e0b8240015f Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 09:54:50 +0200 Subject: Added namespace scopes to more includes for better consistency --- zenutil/zenserverprocess.cpp | 60 +++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 622423cac..c504ce7da 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -17,44 +17,46 @@ ////////////////////////////////////////////////////////////////////////// +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) - { - m_Attributes.lpSecurityDescriptor = &m_Sd; - } - else + const BOOL success = InitializeSecurityDescriptor(&m_Sd, SECURITY_DESCRIPTOR_REVISION); + + if (success) { - zen::ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); + const BOOL bSetOk = SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE); + + if (bSetOk) + { + m_Attributes.lpSecurityDescriptor = &m_Sd; + } + else + { + zen::ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); + } } } - } -}; + }; } // namespace zenutil @@ -628,3 +630,5 @@ ZenServerInstance::GetBaseUri() const return "http://localhost:{}"_format(m_BasePort); } + +} // namespace zen -- cgit v1.2.3 From de65c608c2cefc4be771c11b5bb7132a84fa46eb Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 23:04:11 +0200 Subject: Added better handling for read-only mode --- zenutil/zenserverprocess.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index c504ce7da..c6bee1ed7 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -129,7 +129,8 @@ ZenServerState::Initialize() zen::ThrowLastError("Could not map view of Zen server state"); } - m_Data = reinterpret_cast(pBuf); + m_Data = reinterpret_cast(pBuf); + m_IsReadOnly = false; } bool @@ -221,6 +222,8 @@ ZenServerState::Sweep() return; } + ZEN_ASSERT(m_IsReadOnly == false); + for (int i = 0; i < m_MaxEntryCount; ++i) { ZenServerEntry& Entry = m_Data[i]; -- cgit v1.2.3 From 60898b9fcc57bdc0408f6a48de161a7989b91957 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sat, 18 Sep 2021 11:26:46 +0200 Subject: Simplified AnyUserSecurityAttributes helper --- zenutil/zenserverprocess.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index c6bee1ed7..9e370ae10 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -40,20 +40,16 @@ namespace zenutil { m_Attributes.nLength = sizeof m_Attributes; m_Attributes.bInheritHandle = false; // Disable inheritance - const BOOL success = InitializeSecurityDescriptor(&m_Sd, SECURITY_DESCRIPTOR_REVISION); + const BOOL Success = InitializeSecurityDescriptor(&m_Sd, SECURITY_DESCRIPTOR_REVISION); - if (success) + if (Success) { - const BOOL bSetOk = SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE); - - if (bSetOk) - { - m_Attributes.lpSecurityDescriptor = &m_Sd; - } - else + if (!SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE)) { zen::ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); } + + m_Attributes.lpSecurityDescriptor = &m_Sd; } } }; -- cgit v1.2.3 From 782351959f697fca6b0804c134467b7d9c29da1a Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Mon, 20 Sep 2021 12:08:44 +0200 Subject: Moved more code into zen namespace, for consistency Also removed snapshot_manifest (remnants of vfs prototype) --- zenutil/zenserverprocess.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'zenutil/zenserverprocess.cpp') diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 9e370ae10..55b592ab1 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -46,7 +46,7 @@ namespace zenutil { { if (!SetSecurityDescriptorDacl(&m_Sd, TRUE, (PACL)NULL, FALSE)) { - zen::ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); + ThrowLastError("SetSecurityDescriptorDacl failed", std::source_location::current()); } m_Attributes.lpSecurityDescriptor = &m_Sd; @@ -108,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; @@ -122,7 +122,7 @@ 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(pBuf); @@ -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(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,7 +199,7 @@ ZenServerState::Register(int ListenPort) Entry.Pid = Pid; Entry.Flags = 0; - const zen::Oid SesId = zen::GetSessionId(); + const Oid SesId = GetSessionId(); memcpy(Entry.SessionId, &SesId, sizeof SesId); return &Entry; @@ -226,7 +226,7 @@ ZenServerState::Sweep() 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); @@ -323,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; @@ -334,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; } @@ -406,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 << "\""; @@ -554,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); } -- cgit v1.2.3