2
0
Fork 0
OB-Xd/Modules/gin/utilities/sharedmemory.cpp

161 lines
3.9 KiB
C++
Executable File

/*==============================================================================
Copyright 2018 by Roland Rabien
For more information visit www.rabiensoftware.com
==============================================================================*/
#if JUCE_WINDOWS
typedef enum _SECTION_INFORMATION_CLASS
{
SectionBasicInformation,
SectionImageInformation
} SECTION_INFORMATION_CLASS;
typedef struct _SECTION_BASIC_INFORMATION {
PVOID base;
ULONG attributes;
LARGE_INTEGER size;
} SECTION_BASIC_INFORMATION;
typedef DWORD (WINAPI* NTQUERYSECTION) (HANDLE, SECTION_INFORMATION_CLASS, PVOID, ULONG, PULONG);
class SharedMemory::Impl
{
public:
Impl (String name, int sz) : size (sz)
{
String shareName = "Local\\" + File::createLegalFileName (name);
fileMapping = OpenFileMappingW (FILE_MAP_ALL_ACCESS, FALSE, shareName.toWideCharPointer());
if (fileMapping == nullptr)
fileMapping = CreateFileMappingW (INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, sz, shareName.toWideCharPointer());
if (HMODULE dll = LoadLibrary ("ntdll.dll"))
{
NTQUERYSECTION ntQuerySection = (NTQUERYSECTION) GetProcAddress (dll, "NtQuerySection");
if (ntQuerySection != nullptr)
{
SECTION_BASIC_INFORMATION SectionInfo = { 0 };
ntQuerySection (fileMapping, SectionBasicInformation, &SectionInfo, sizeof (SectionInfo), 0);
if (SectionInfo.size.QuadPart > 0)
size = int (SectionInfo.size.QuadPart);
}
FreeLibrary (dll);
}
data = MapViewOfFile (fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
}
~Impl()
{
if (data != nullptr)
UnmapViewOfFile (data);
if (fileMapping != nullptr)
CloseHandle (fileMapping);
}
static void remove (const String& name)
{
ignoreUnused (name);
}
HANDLE fileMapping = nullptr;
int size = 0;
void* data = nullptr;
};
#else
class SharedMemory::Impl
{
public:
Impl (String name, int sz) : size (sz)
{
bool needsInit = false;
shareName = "/jshm" + File::createLegalFileName (name);
fd = shm_open (shareName.toRawUTF8(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd == -1)
fd = shm_open (shareName.toRawUTF8(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
else
needsInit = true;
if (fd == -1)
{
size = 0;
return;
}
if (needsInit && ftruncate (fd, size) == -1)
{
size = 0;
return;
}
struct stat statbuf;
if (fstat (fd, &statbuf) == -1)
{
size = 0;
return;
}
size = int (statbuf.st_size);
data = mmap (nullptr, size_t (size), PROT_WRITE, MAP_SHARED, fd, 0);
jassert (data != nullptr);
if (data != nullptr && needsInit)
memset (data, 0, sizeof (data));
}
~Impl()
{
if (data != nullptr)
munmap (data, size_t (size));
if (fd != -1)
close (fd);
shm_unlink (shareName.toRawUTF8());
}
static void remove (const String& name)
{
String shareName = "/jshm" + File::createLegalFileName (name);
shm_unlink (shareName.toRawUTF8());
}
String shareName;
int size;
void* data = nullptr;
int fd;
};
#endif
SharedMemory::SharedMemory (const String& name, int size)
{
impl = std::make_unique<Impl> (name, size);
}
SharedMemory::~SharedMemory()
{
}
void* SharedMemory::getData()
{
return impl->data;
}
int SharedMemory::getSize()
{
return impl->size;
}
void SharedMemory::remove (const String& name)
{
Impl::remove (name);
}