/* A template function which creates/attaches shm seg handle * to the shared memory. Used by user-exposed functions below */ static inline int MPL_shm_seg_create_attach_templ(MPL_shm_hnd_t hnd, intptr_t seg_sz, void **shm_addr_ptr, int offset, int flag) { HANDLE lhnd = INVALID_HANDLE_VALUE; int rc = MPL_SHM_SUCCESS; ULARGE_INTEGER seg_sz_large; seg_sz_large.QuadPart = seg_sz; if (!MPLI_shm_ghnd_is_valid(hnd)) { rc = MPLI_shm_ghnd_set_uniq(hnd); if (rc) { goto fn_exit; } } if (flag & MPLI_SHM_FLAG_SHM_CREATE) { lhnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, seg_sz_large.HighPart, seg_sz_large.LowPart, MPLI_shm_ghnd_get_by_ref(hnd)); if (lhnd == NULL) { rc = MPL_SHM_EINTERN; goto fn_exit; } MPLI_shm_lhnd_set(hnd, lhnd); } else { if (!MPLI_shm_lhnd_is_valid(hnd)) { /* Strangely OpenFileMapping() returns NULL on error! */ lhnd = OpenFileMapping(FILE_MAP_WRITE, FALSE, MPLI_shm_ghnd_get_by_ref(hnd)); if (lhnd == NULL) { rc = MPL_SHM_EINTERN; goto fn_exit; } MPLI_shm_lhnd_set(hnd, lhnd); } } if (flag & MPLI_SHM_FLAG_SHM_ATTACH) { if (flag & MPLI_SHM_FLAG_FIXED_ADDR) { void *start_addr = (void *) *shm_addr_ptr; /* The start_addr must be a multiple of the system's memory allocation granularity, * or the function fails. To determine the memory allocation granularity of the system, * use the GetSystemInfo function. If there is not enough address space at the * specified address, the function fails. * If the function fails, the return value is NULL.*/ *shm_addr_ptr = MapViewOfFileEx(MPLI_shm_lhnd_get(hnd), FILE_MAP_WRITE, 0, offset, 0, start_addr); } else { *shm_addr_ptr = MapViewOfFile(MPLI_shm_lhnd_get(hnd), FILE_MAP_WRITE, 0, offset, 0); } if (*shm_addr_ptr == NULL) { rc = MPL_SHM_EINVAL; } } fn_exit: return rc; }
/* Remove a shared memory segment * hnd : Handle to the shared memory segment to be removed */ int MPL_shm_seg_remove(MPL_shm_hnd_t hnd) { struct shmid_ds ds; int rc = -1; rc = shmctl(MPLI_shm_lhnd_get(hnd), IPC_RMID, &ds); return (rc == 0) ? MPL_SHM_SUCCESS : MPL_SHM_EINTERN; }
inline int MPLI_shm_lhnd_close(MPL_shm_hnd_t hnd) { MPLI_shm_lhnd_t lhnd = MPLI_SHM_LHND_INVALID; lhnd = MPLI_shm_lhnd_get(hnd); if (lhnd != MPLI_SHM_LHND_INVALID) { if (close(lhnd) == 0) { MPLI_shm_lhnd_set(hnd, MPLI_SHM_LHND_INIT_VAL); } else { /* close() failed */ return -1; } } return 0; }
/* A template function which creates/attaches shm seg handle * to the shared memory. Used by user-exposed functions below */ static inline int MPL_shm_seg_create_attach_templ(MPL_shm_hnd_t hnd, intptr_t seg_sz, void **shm_addr_ptr, int offset, int flag) { int rc = MPL_SHM_SUCCESS; int lhnd = -1; if (flag & MPLI_SHM_FLAG_SHM_CREATE) { lhnd = shmget(IPC_PRIVATE, seg_sz, IPC_CREAT | S_IRWXU); MPLI_shm_lhnd_set(hnd, lhnd); rc = MPLI_shm_ghnd_alloc(hnd, MPL_MEM_SHM); if (rc) { goto fn_exit; } rc = MPLI_shm_ghnd_set_by_val(hnd, "%d", lhnd); if (rc != MPL_SHM_SUCCESS) { goto fn_exit; } } else { /* Open an existing shared memory seg */ if (!MPLI_shm_lhnd_is_valid(hnd)) { lhnd = atoi(MPLI_shm_ghnd_get_by_ref(hnd)); MPLI_shm_lhnd_set(hnd, lhnd); } } if (flag & MPLI_SHM_FLAG_SHM_ATTACH) { const void *start_addr = NULL; /* Caller ensures that shmaddr must be a page-aligned address * at which the attach occurs. EINVAL error would result if a * mapping already exists in this address range or the address * is not page-aligned. */ if (flag & MPLI_SHM_FLAG_FIXED_ADDR) start_addr = (const void *) *shm_addr_ptr; /* Attach to shared mem seg */ *shm_addr_ptr = shmat(MPLI_shm_lhnd_get(hnd), start_addr, 0x0); if (*shm_addr_ptr == (void *) -1) { rc = MPL_SHM_EINVAL; } } fn_exit: return rc; }
static inline int MPL_shm_seg_create_attach_templ( MPL_shm_hnd_t hnd, intptr_t seg_sz, char **shm_addr_ptr, int offset, int flag) { HANDLE lhnd = INVALID_HANDLE_VALUE; int rc = -1; ULARGE_INTEGER seg_sz_large; seg_sz_large.QuadPart = seg_sz; if(!MPLI_shm_ghnd_is_valid(hnd)){ rc = MPLI_shm_ghnd_set_uniq(hnd); } if(flag & MPLI_SHM_FLAG_SHM_CREATE){ lhnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, seg_sz_large.HighPart, seg_sz_large.LowPart, MPLI_shm_ghnd_get_by_ref(hnd)); MPLI_shm_lhnd_set(hnd, lhnd); } else{ if(!MPLI_shm_lhnd_is_valid(hnd)){ /* Strangely OpenFileMapping() returns NULL on error! */ lhnd = OpenFileMapping(FILE_MAP_WRITE, FALSE, MPLI_shm_ghnd_get_by_ref(hnd)); MPLI_shm_lhnd_set(hnd, lhnd); } } if(flag & MPLI_SHM_FLAG_SHM_ATTACH){ *shm_addr_ptr = (char *)MapViewOfFile(MPLI_shm_lhnd_get(hnd), FILE_MAP_WRITE, 0, offset, 0); } fn_exit: return rc; fn_fail: goto fn_exit; }