aboutsummaryrefslogtreecommitdiff
path: root/zenutil/zenserverprocess.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenutil/zenserverprocess.cpp')
-rw-r--r--zenutil/zenserverprocess.cpp147
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