#include "precompile.h" #include "shm.h" #include /* Detach from a shared mem area based on its address */ TOOLKIT_API int shmdt(const void *shmaddr) { if (UnmapViewOfFile((LPCVOID *) shmaddr)) return 0; else return -1; } /* Attach to an existing area */ TOOLKIT_API void * shmat(int memId, void *shmaddr, int flag) { DWORD dwAccessFlag = (flag & SHM_RDONLY) ? FILE_MAP_READ : (FILE_MAP_WRITE | FILE_MAP_READ); /* TODO -- shmat needs to count # attached to shared mem */ void *lpmem = MapViewOfFileEx((HANDLE) memId, dwAccessFlag, 0, 0, /* (DWORD)pshmdsc->segsize */ 0, shmaddr); if (lpmem == NULL) { DWORD dwError = GetLastError(); lpmem = (void *) -1; } return lpmem; } /* Control a shared mem area */ TOOLKIT_API int shmctl(int shmid, int flag, struct shmid_ds * dummy) { if (flag == IPC_RMID) { /* Delete the area */ CloseHandle((HANDLE) shmid); return 0; } if (flag == IPC_STAT) { /* Can only test for if exists */ int hmap = shmget(shmid, 0, 0); if (hmap < 0) { /* Shared memory does not exist */ return -1; } else { /* Shared memory does exist and must be in use */ shmctl(hmap, IPC_RMID, NULL); /* Release our hold on it */ return 0; } } return -1; } static int shmget_str(const char *szShareMem, int size, int flag) { HANDLE hmap; DWORD dwRet; if (flag & IPC_CREAT) { hmap = CreateFileMappingA((HANDLE) 0xFFFFFFFF, /* Use the swap file */ NULL, PAGE_READWRITE, /* Memory is Read/Write */ 0L, /* Size Upper 32 Bits */ (DWORD) size, /* Size Lower 32 bits */ szShareMem); } else { hmap = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, szShareMem); if (!hmap) { return -1; } } dwRet = GetLastError(); if (dwRet == ERROR_ALREADY_EXISTS && hmap && (flag & IPC_CREAT & IPC_EXCL)) { /* Caller wanted to create the segment -- error if already exists */ CloseHandle(hmap); return -1; } else if (!hmap) { /* Unable to get shared memory */ return -1; } return (int) hmap; } /* Get an area based on the IPC key */ TOOLKIT_API int shmget(int memKey, int size, int flag) { char szShareMem[32]; sprintf(szShareMem, "shm.%d", memKey); return shmget_str(szShareMem, size, flag); }