160 lines
3.9 KiB
C++
Executable file
160 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);
|
|
}
|