aboutsummaryrefslogtreecommitdiff
path: root/zenutil/zenserverprocess.cpp
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2021-10-29 14:31:23 +0200
committerMartin Ridgers <[email protected]>2021-10-29 14:33:08 +0200
commita4e456ef7a9ff6fc37b0bd4ec0dfc25a282cafb3 (patch)
tree81ee94ea6ce6229aa80c4284e120d3720c2537eb /zenutil/zenserverprocess.cpp
parentUse zen::GetCurrentProcessId() instead of MS' _getpid() (diff)
downloadzen-a4e456ef7a9ff6fc37b0bd4ec0dfc25a282cafb3.tar.xz
zen-a4e456ef7a9ff6fc37b0bd4ec0dfc25a282cafb3.zip
Implemented ZenServerState's shared memory layer for POSIX
Diffstat (limited to 'zenutil/zenserverprocess.cpp')
-rw-r--r--zenutil/zenserverprocess.cpp95
1 files changed, 71 insertions, 24 deletions
diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp
index ab547b98c..1974772d2 100644
--- a/zenutil/zenserverprocess.cpp
+++ b/zenutil/zenserverprocess.cpp
@@ -8,13 +8,17 @@
#include <zencore/logging.h>
#include <zencore/session.h>
#include <zencore/string.h>
+#include <zencore/thread.h>
+#include <atomic>
#include <source_location>
#if ZEN_PLATFORM_WINDOWS
# include <atlbase.h>
# include <shellapi.h>
# include <zencore/windows.h>
+#else
+# include <sys/mman.h>
#endif
//////////////////////////////////////////////////////////////////////////
@@ -22,6 +26,7 @@
namespace zen {
namespace zenutil {
+#if ZEN_PLATFORM_WINDOWS
class SecurityAttributes
{
public:
@@ -55,6 +60,7 @@ namespace zenutil {
}
}
};
+#endif // ZEN_PLATFORM_WINDOWS
} // namespace zenutil
@@ -74,59 +80,85 @@ ZenServerState::~ZenServerState()
m_OurEntry = nullptr;
}
+#if ZEN_PLATFORM_WINDOWS
if (m_Data)
{
UnmapViewOfFile(m_Data);
- m_Data = nullptr;
}
if (m_hMapFile)
{
CloseHandle(m_hMapFile);
}
+#else
+ if (m_Data != nullptr)
+ {
+ munmap(m_Data, m_MaxEntryCount * sizeof(ZenServerEntry));
+ }
+
+ int Fd = int(intptr_t(m_hMapFile));
+ close(Fd);
+#endif
+
+ m_Data = nullptr;
}
void
ZenServerState::Initialize()
{
+ size_t MapSize = m_MaxEntryCount * sizeof(ZenServerEntry);
+
+#if ZEN_PLATFORM_WINDOWS
// TODO: there's a small chance of a race here, this logic could be tightened up with a mutex to
// ensure only a single process at a time creates the mapping
- if (HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"Global\\ZenMap"))
- {
- m_hMapFile = hMap;
- }
- else
+ HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"Global\\ZenMap");
+ if (hMap == NULL)
{
// Security attributes to enable any user to access state
zenutil::AnyUserSecurityAttributes Attrs;
- hMap = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
- Attrs.Attributes(), // allow anyone to access
- PAGE_READWRITE, // read/write access
- 0, // maximum object size (high-order DWORD)
- m_MaxEntryCount * sizeof(ZenServerEntry), // maximum object size (low-order DWORD)
- L"Global\\ZenMap"); // name of mapping object
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
+ Attrs.Attributes(), // allow anyone to access
+ PAGE_READWRITE, // read/write access
+ 0, // maximum object size (high-order DWORD)
+ MapSize, // maximum object size (low-order DWORD)
+ L"Global\\ZenMap"); // name of mapping object
if (hMap == NULL)
{
ThrowLastError("Could not open or create file mapping object for Zen server state");
}
-
- m_hMapFile = hMap;
}
- void* pBuf = MapViewOfFile(m_hMapFile, // handle to map object
+ void* pBuf = MapViewOfFile(hMap, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0, // offset high
0, // offset low
- m_MaxEntryCount * sizeof(ZenServerEntry));
+ MapSize);
if (pBuf == NULL)
{
ThrowLastError("Could not map view of Zen server state");
}
+#else
+ int Fd = shm_open("UnrealEngineZen", O_RDWR|O_CREAT, 0666);
+ if (Fd < 0)
+ {
+ ThrowLastError("Could not open a shared memory object");
+ }
+ void* hMap = (void*)intptr_t(Fd);
+ ftruncate(Fd, MapSize);
+
+ void* pBuf = mmap(nullptr, MapSize, PROT_READ|PROT_WRITE, MAP_SHARED, Fd, 0);
+ if (pBuf == MAP_FAILED)
+ {
+ ThrowLastError("Could not map view of Zen server state");
+ }
+#endif
+
+ m_hMapFile = hMap;
m_Data = reinterpret_cast<ZenServerEntry*>(pBuf);
m_IsReadOnly = false;
}
@@ -134,27 +166,42 @@ ZenServerState::Initialize()
bool
ZenServerState::InitializeReadOnly()
{
- if (HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"Global\\ZenMap"))
- {
- m_hMapFile = hMap;
- }
- else
+ size_t MapSize = m_MaxEntryCount * sizeof(ZenServerEntry);
+
+#if ZEN_PLATFORM_WINDOWS
+ HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"Global\\ZenMap");
+ if (hMap == NULL)
{
return false;
}
- void* pBuf = MapViewOfFile(m_hMapFile, // handle to map object
+ void* pBuf = MapViewOfFile(hMap, // handle to map object
FILE_MAP_READ, // read permission
0, // offset high
0, // offset low
- m_MaxEntryCount * sizeof(ZenServerEntry));
+ MapSize);
if (pBuf == NULL)
{
ThrowLastError("Could not map view of Zen server state");
}
+#else
+ int Fd = shm_open("UnrealEngineZen", O_RDONLY, 0666);
+ if (Fd < 0)
+ {
+ return false;
+ }
+ void* hMap = (void*)intptr_t(Fd);
+
+ void* pBuf = mmap(nullptr, MapSize, PROT_READ, MAP_PRIVATE, Fd, 0);
+ if (pBuf == MAP_FAILED)
+ {
+ ThrowLastError("Could not map read-only view of Zen server state");
+ }
+#endif
- m_Data = reinterpret_cast<ZenServerEntry*>(pBuf);
+ m_hMapFile = hMap;
+ m_Data = reinterpret_cast<ZenServerEntry*>(pBuf);
return true;
}