Files
UnrealEngine/Engine/Source/Runtime/IPC/Public/IPC.h
2025-05-18 13:04:45 +08:00

179 lines
4.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*==============================================================================
IPC.h: Public interface for inteprocess communication module
==============================================================================*/
#pragma once
#include "CoreMinimal.h"
#include "HAL/PlatformProcess.h"
namespace IPC
{
/**
* Example class for synchronized interprocess memory
*/
class FSynchronizedInterprocessMemory
{
/** Lock that guards access to the memory region */
FPlatformProcess::FSemaphore * Mutex;
/** Low-level memory region */
FPlatformMemory::FSharedMemoryRegion * Memory;
/**
* Constructor
*/
FSynchronizedInterprocessMemory(FPlatformProcess::FSemaphore * InMutex, FPlatformMemory::FSharedMemoryRegion * InMemory)
: Mutex(InMutex)
, Memory(InMemory)
{
check(Mutex);
check(Memory);
}
public:
/**
* Destructor
*/
~FSynchronizedInterprocessMemory()
{
if (Mutex)
{
FPlatformProcess::DeleteInterprocessSynchObject(Mutex);
Mutex = NULL;
}
if (Memory)
{
FPlatformMemory::UnmapNamedSharedMemoryRegion(Memory);
Memory = NULL;
}
}
/**
* Creates a new synchronized interprocess memory object
*/
static FSynchronizedInterprocessMemory * Create(const TCHAR* Name, SIZE_T Size)
{
FPlatformMemory::FSharedMemoryRegion * Memory = FPlatformMemory::MapNamedSharedMemoryRegion(Name, true,
FPlatformMemory::ESharedMemoryAccess::Read | FPlatformMemory::ESharedMemoryAccess::Write, Size);
if (!Memory)
{
return NULL;
}
// initialize memory with zeroes
check(Memory->GetAddress());
FMemory::Memzero(Memory->GetAddress(), Memory->GetSize());
FPlatformProcess::FSemaphore * Mutex = FPlatformProcess::NewInterprocessSynchObject(Name, true);
if (!Mutex)
{
FPlatformMemory::UnmapNamedSharedMemoryRegion(Memory);
return NULL;
}
return new FSynchronizedInterprocessMemory(Mutex, Memory);
}
/**
* Opens existing synchronized interprocess memory object
*/
static FSynchronizedInterprocessMemory * OpenExisting(const TCHAR* Name, SIZE_T Size)
{
FPlatformMemory::FSharedMemoryRegion * Memory = FPlatformMemory::MapNamedSharedMemoryRegion(Name, false,
FPlatformMemory::ESharedMemoryAccess::Read | FPlatformMemory::ESharedMemoryAccess::Write, Size);
if (!Memory)
{
return NULL;
}
FPlatformProcess::FSemaphore * Mutex = FPlatformProcess::NewInterprocessSynchObject(Name, false);
if (!Mutex)
{
FPlatformMemory::UnmapNamedSharedMemoryRegion(Memory);
return NULL;
}
return new FSynchronizedInterprocessMemory(Mutex, Memory);
}
/**
* Writes string to shared memory
*
* @param String string to write
* @param MaxMillisecondsToWait max milliseconds to wait (if 0, wait forever)
*
* @return true if was able to write
*/
bool Write(const FString& String, uint32 MaxMillisecondsToWait = 0)
{
check(Mutex);
check(Memory);
// acquire
if (!MaxMillisecondsToWait)
{
Mutex->Lock();
}
else
{
if (!Mutex->TryLock(MaxMillisecondsToWait * 1000000ULL)) // 1ms = 10^6 ns
{
return false;
}
}
// we have exclusive ownership now!
TCHAR* RawMemory = reinterpret_cast< TCHAR* >(Memory->GetAddress() );
FCString::Strncpy(RawMemory, *String, Memory->GetSize());
// relinquish
Mutex->Unlock();
return true;
}
/**
* Reads a string from shared memory
*
* @param String string to read into
* @param MaxMillisecondsToWait max milliseconds to wait (if 0, wait forever)
*
* @return true if read withing given time
*/
bool Read(FString& OutString, uint32 MaxMillisecondsToWait = 0)
{
check(Mutex);
check(Memory);
// acquire
if (!MaxMillisecondsToWait)
{
Mutex->Lock();
}
else
{
if (!Mutex->TryLock(MaxMillisecondsToWait * 1000000ULL)) // 1ms = 10^6 ns
{
return false;
}
}
// we have exclusive ownership now!
const TCHAR* RawMemory = reinterpret_cast< const TCHAR* >( Memory->GetAddress() );
OutString = FString(RawMemory);
// relinquish
Mutex->Unlock();
return true;
}
};
}; // namespace IPC