123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- #include "shmat.h"
- #include <util/generic/guid.h>
- #if defined(_win_)
- #include <stdio.h>
- #include "winint.h"
- #elif defined(_bionic_)
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/syscall.h>
- #elif defined(_unix_)
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #endif
- #if defined(_cygwin_)
- #define WINAPI __stdcall
- #define FILE_MAP_ALL_ACCESS ((long)983071)
- #define PAGE_READWRITE 4
- #define FALSE 0
- extern "C" {
- using HANDLE = OS_HANDLE;
- using BOOL = int;
- using DWORD = ui32;
- using LPCTSTR = const char*;
- using LPVOID = void*;
- using LPCVOID = void const*;
- using SIZE_T = size_t;
- BOOL WINAPI CloseHandle(HANDLE hObject);
- HANDLE WINAPI OpenFileMappingA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName);
- LPVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject, DWORD DesiredAccess, DWORD FileOffsetHigh, DWORD FileOffsetLow, SIZE_T NumberOfBytesToMap);
- HANDLE WINAPI CreateFileMappingA(HANDLE hFile, LPVOID lpAttributes, DWORD flProtect, DWORD MaximumSizeHigh, DWORD MaximumSizeLow, LPCTSTR lpName);
- BOOL WINAPI UnmapViewOfFile(LPCVOID lpBaseAddress);
- DWORD WINAPI GetLastError(void);
- }
- #endif
- #if defined(_bionic_)
- namespace {
- #if !defined(__i386__)
- static int shmget(key_t key, size_t size, int flag) {
- if (size > PTRDIFF_MAX) {
- size = SIZE_MAX;
- }
- return syscall(__NR_shmget, key, size, flag);
- }
- static void* shmat(int id, const void* addr, int flag) {
- return (void*)syscall(__NR_shmat, id, addr, flag);
- }
- static int shmctl(int id, int cmd, void* buf) {
- return syscall(__NR_shmctl, id, cmd | IPC_64, buf);
- }
- static int shmdt(const void* addr) {
- return syscall(__NR_shmdt, addr);
- }
- #else
- #define IPCOP_shmat 21
- #define IPCOP_shmdt 22
- #define IPCOP_shmget 23
- #define IPCOP_shmctl 24
- static int shmget(key_t key, size_t size, int flag) {
- return syscall(__NR_ipc, IPCOP_shmget, key, size, flag, 0);
- }
- static void* shmat(int id, const void* addr, int flag) {
- void* retval;
- long res = syscall(__NR_ipc, IPCOP_shmat, id, flag, (long)&retval, addr);
- return (res >= 0) ? retval : (void*)-1;
- }
- static int shmctl(int id, int cmd, void* buf) {
- return syscall(__NR_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf);
- }
- static int shmdt(const void* addr) {
- return syscall(__NR_ipc, IPCOP_shmdt, 0, 0, 0, addr);
- }
- #endif
- } // namespace
- #endif
- TSharedMemory::TSharedMemory()
- : Handle(INVALID_FHANDLE)
- , Data(nullptr)
- , Size(0)
- {
- }
- #if defined(_win_)
- static void FormatName(char* buf, const TGUID& id) {
- sprintf(buf, "Global\\shmat-%s", GetGuidAsString(id).c_str());
- }
- bool TSharedMemory::Open(const TGUID& id, int size) {
- // Y_ASSERT(Data == 0);
- Id = id;
- Size = size;
- char name[100];
- FormatName(name, Id);
- Handle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name);
- if (Handle == 0) {
- return false;
- }
- Data = MapViewOfFile(Handle, FILE_MAP_ALL_ACCESS, 0, 0, size);
- if (Data == 0) {
- // Y_ASSERT(0);
- CloseHandle(Handle);
- Handle = INVALID_OS_HANDLE;
- return false;
- }
- return true;
- }
- bool TSharedMemory::Create(int size) {
- // Y_ASSERT(Data == 0);
- Size = size;
- CreateGuid(&Id);
- char name[100];
- FormatName(name, Id);
- Handle = CreateFileMappingA(INVALID_OS_HANDLE, nullptr, PAGE_READWRITE, 0, size, name);
- if (Handle == 0) {
- // Y_ASSERT(0);
- return false;
- }
- Data = MapViewOfFile(Handle, FILE_MAP_ALL_ACCESS, 0, 0, size);
- if (Data == 0) {
- // Y_ASSERT(0);
- CloseHandle(Handle);
- Handle = INVALID_OS_HANDLE;
- return false;
- }
- return true;
- }
- TSharedMemory::~TSharedMemory() {
- if (Data) {
- UnmapViewOfFile(Handle);
- }
- CloseHandle(Handle);
- }
- #else
- static key_t GetKey(const TGUID& id) {
- i64 id64 = (ui64)(((ui64)id.dw[0] + (ui64)id.dw[2]) << 32) + (ui64)id.dw[1] + (ui64)id.dw[3];
- return id64;
- }
- bool TSharedMemory::Open(const TGUID& id, int size) {
- Y_ABORT_UNLESS(id, "invalid shared memory guid: %s", GetGuidAsString(id).data());
- // Y_ASSERT(Data == 0);
- Size = size;
- key_t k = GetKey(id);
- int shmId = shmget(k, Size, 0777); // do not fill Handle, since IPC_RMID should be called by owner
- if (shmId < 0) {
- return false;
- }
- Data = shmat(shmId, nullptr, 0);
- if (Data == nullptr) {
- // Y_ASSERT(0);
- return false;
- }
- return true;
- }
- bool TSharedMemory::Create(int size) {
- // Y_ASSERT(Data == 0);
- Size = size;
- CreateGuid(&Id);
- key_t k = GetKey(Id);
- Handle = shmget(k, Size, IPC_CREAT | IPC_EXCL | 0777);
- if (Handle < 0) {
- // Y_ASSERT(0);
- return false;
- }
- Data = shmat(Handle, nullptr, 0);
- if (Data == (void*)-1) {
- // Y_ASSERT(0);
- shmctl(Handle, IPC_RMID, nullptr);
- Handle = -1;
- return false;
- }
- return true;
- }
- TSharedMemory::~TSharedMemory() {
- if (Data) {
- shmdt(Data);
- }
- if (Handle >= 0) {
- shmctl(Handle, IPC_RMID, nullptr);
- }
- }
- #endif
|