1e5c31af7Sopenharmony_ci#if defined(_WIN32) 2e5c31af7Sopenharmony_citypedef void *HANDLE; 3e5c31af7Sopenharmony_ci#else 4e5c31af7Sopenharmony_ci#include <semaphore.h> 5e5c31af7Sopenharmony_ci#endif 6e5c31af7Sopenharmony_ci 7e5c31af7Sopenharmony_citypedef struct ipc_sharedmemory_ 8e5c31af7Sopenharmony_ci{ 9e5c31af7Sopenharmony_ci char* name; 10e5c31af7Sopenharmony_ci unsigned char* data; 11e5c31af7Sopenharmony_ci size_t size; 12e5c31af7Sopenharmony_ci#if defined(_WIN32) 13e5c31af7Sopenharmony_ci HANDLE handle; 14e5c31af7Sopenharmony_ci#else 15e5c31af7Sopenharmony_ci int fd; 16e5c31af7Sopenharmony_ci#endif 17e5c31af7Sopenharmony_ci} ipc_sharedmemory; 18e5c31af7Sopenharmony_ci 19e5c31af7Sopenharmony_citypedef struct ipc_sharedsemaphore_ 20e5c31af7Sopenharmony_ci{ 21e5c31af7Sopenharmony_ci char* name; 22e5c31af7Sopenharmony_ci#if defined(_WIN32) 23e5c31af7Sopenharmony_ci HANDLE handle; 24e5c31af7Sopenharmony_ci#else 25e5c31af7Sopenharmony_ci sem_t* semaphore; 26e5c31af7Sopenharmony_ci#endif 27e5c31af7Sopenharmony_ci} ipc_sharedsemaphore; 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#if defined(_WIN32) 30e5c31af7Sopenharmony_ci#include <windows.h> 31e5c31af7Sopenharmony_ci#else // !_WIN32 32e5c31af7Sopenharmony_ci#include <fcntl.h> 33e5c31af7Sopenharmony_ci#include <sys/mman.h> 34e5c31af7Sopenharmony_ci#include <sys/stat.h> 35e5c31af7Sopenharmony_ci#include <unistd.h> 36e5c31af7Sopenharmony_ci#include <errno.h> 37e5c31af7Sopenharmony_ci#endif // !_WIN32 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cistatic char* ipc_strdup (char* src) 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci int i; 42e5c31af7Sopenharmony_ci int len = 0; 43e5c31af7Sopenharmony_ci char* dst = NULL; 44e5c31af7Sopenharmony_ci while (src[len]) len++; 45e5c31af7Sopenharmony_ci#if !defined(_WIN32) 46e5c31af7Sopenharmony_ci len++; 47e5c31af7Sopenharmony_ci#endif 48e5c31af7Sopenharmony_ci dst = (char*)malloc(len + 1); 49e5c31af7Sopenharmony_ci if (!dst) return NULL; 50e5c31af7Sopenharmony_ci dst[len] = 0; 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci#if defined(_WIN32) 53e5c31af7Sopenharmony_ci for (i = 0; i < len; i++) 54e5c31af7Sopenharmony_ci dst[i] = src[i]; 55e5c31af7Sopenharmony_ci#else 56e5c31af7Sopenharmony_ci dst[0] = '/'; 57e5c31af7Sopenharmony_ci for (i = 0; i < len - 1; i++) 58e5c31af7Sopenharmony_ci dst[i + 1] = src[i]; 59e5c31af7Sopenharmony_ci#endif 60e5c31af7Sopenharmony_ci return dst; 61e5c31af7Sopenharmony_ci} 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_civoid ipc_mem_init (ipc_sharedmemory* mem, char* name, size_t size) 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci mem->name = ipc_strdup(name); 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci mem->size = size; 68e5c31af7Sopenharmony_ci mem->data = NULL; 69e5c31af7Sopenharmony_ci#if defined(_WIN32) 70e5c31af7Sopenharmony_ci mem->handle = 0; 71e5c31af7Sopenharmony_ci#else 72e5c31af7Sopenharmony_ci mem->fd = -1; 73e5c31af7Sopenharmony_ci#endif 74e5c31af7Sopenharmony_ci} 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ciunsigned char* ipc_mem_access (ipc_sharedmemory* mem) 77e5c31af7Sopenharmony_ci{ 78e5c31af7Sopenharmony_ci return mem->data; 79e5c31af7Sopenharmony_ci} 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_civoid ipc_sem_init (ipc_sharedsemaphore* sem, char* name) 82e5c31af7Sopenharmony_ci{ 83e5c31af7Sopenharmony_ci sem->name = ipc_strdup(name); 84e5c31af7Sopenharmony_ci#if defined(_WIN32) 85e5c31af7Sopenharmony_ci sem->handle = 0; 86e5c31af7Sopenharmony_ci#else 87e5c31af7Sopenharmony_ci sem->semaphore = NULL; 88e5c31af7Sopenharmony_ci#endif 89e5c31af7Sopenharmony_ci} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci#if defined(_WIN32) 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ciint ipc_mem_open_existing (ipc_sharedmemory* mem) 94e5c31af7Sopenharmony_ci{ 95e5c31af7Sopenharmony_ci mem->handle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, mem->name); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci if (!mem->handle) 98e5c31af7Sopenharmony_ci return -1; 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci mem->data = (unsigned char*)MapViewOfFile(mem->handle, FILE_MAP_ALL_ACCESS, 0, 0, mem->size); 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci if (!mem->data) 103e5c31af7Sopenharmony_ci return -1; 104e5c31af7Sopenharmony_ci return 0; 105e5c31af7Sopenharmony_ci} 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ciint ipc_mem_create (ipc_sharedmemory* mem) 108e5c31af7Sopenharmony_ci{ 109e5c31af7Sopenharmony_ci mem->handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)mem->size, mem->name); 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_ci if (!mem->handle) 112e5c31af7Sopenharmony_ci return -1; 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci mem->data = (unsigned char*)MapViewOfFile(mem->handle, FILE_MAP_ALL_ACCESS, 0, 0, mem->size); 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci if (!mem->data) 117e5c31af7Sopenharmony_ci return -1; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci return 0; 120e5c31af7Sopenharmony_ci} 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_civoid ipc_mem_close (ipc_sharedmemory* mem) 123e5c31af7Sopenharmony_ci{ 124e5c31af7Sopenharmony_ci if (mem->data != NULL) 125e5c31af7Sopenharmony_ci { 126e5c31af7Sopenharmony_ci UnmapViewOfFile(mem->data); 127e5c31af7Sopenharmony_ci mem->data = NULL; 128e5c31af7Sopenharmony_ci } 129e5c31af7Sopenharmony_ci free(mem->name); 130e5c31af7Sopenharmony_ci mem->name = NULL; 131e5c31af7Sopenharmony_ci mem->size = 0; 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ciint ipc_sem_create (ipc_sharedsemaphore* sem, int initialvalue) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci sem->handle = CreateSemaphoreA(NULL, initialvalue, 0x7fffffff, sem->name); 137e5c31af7Sopenharmony_ci if (!sem->handle) 138e5c31af7Sopenharmony_ci return -1; 139e5c31af7Sopenharmony_ci return 0; 140e5c31af7Sopenharmony_ci} 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_civoid ipc_sem_close (ipc_sharedsemaphore* sem) 143e5c31af7Sopenharmony_ci{ 144e5c31af7Sopenharmony_ci CloseHandle(sem->handle); 145e5c31af7Sopenharmony_ci free(sem->name); 146e5c31af7Sopenharmony_ci sem->handle = 0; 147e5c31af7Sopenharmony_ci} 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_civoid ipc_sem_increment (ipc_sharedsemaphore* sem) 150e5c31af7Sopenharmony_ci{ 151e5c31af7Sopenharmony_ci ReleaseSemaphore(sem->handle, 1, NULL); 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_civoid ipc_sem_decrement (ipc_sharedsemaphore* sem) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci WaitForSingleObject(sem->handle, INFINITE); 157e5c31af7Sopenharmony_ci} 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ciint ipc_sem_try_decrement (ipc_sharedsemaphore* sem) 160e5c31af7Sopenharmony_ci{ 161e5c31af7Sopenharmony_ci DWORD ret = WaitForSingleObject(sem->handle, 0); 162e5c31af7Sopenharmony_ci if (ret == WAIT_OBJECT_0) 163e5c31af7Sopenharmony_ci return 1; 164e5c31af7Sopenharmony_ci return 0; 165e5c31af7Sopenharmony_ci} 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci#else // !defined(_WIN32) 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ciint ipc_mem_open_existing (ipc_sharedmemory* mem) 170e5c31af7Sopenharmony_ci{ 171e5c31af7Sopenharmony_ci mem->fd = shm_open(mem->name, O_RDWR, 0755); 172e5c31af7Sopenharmony_ci if (mem->fd < 0) 173e5c31af7Sopenharmony_ci return -1; 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci mem->data = (unsigned char *)mmap(NULL, mem->size, PROT_READ | PROT_WRITE, MAP_SHARED, mem->fd, 0); 176e5c31af7Sopenharmony_ci if (!mem->data) 177e5c31af7Sopenharmony_ci return -1; 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci return 0; 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ciint ipc_mem_create (ipc_sharedmemory* mem) 183e5c31af7Sopenharmony_ci{ 184e5c31af7Sopenharmony_ci int ret; 185e5c31af7Sopenharmony_ci ret = shm_unlink(mem->name); 186e5c31af7Sopenharmony_ci if (ret < 0 && errno != ENOENT) 187e5c31af7Sopenharmony_ci return -1; 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci mem->fd = shm_open(mem->name, O_CREAT | O_RDWR, 0755); 190e5c31af7Sopenharmony_ci if (mem->fd < 0) 191e5c31af7Sopenharmony_ci return -1; 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_ci ftruncate(mem->fd, mem->size); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci mem->data = (unsigned char *)mmap(NULL, mem->size, PROT_READ | PROT_WRITE, MAP_SHARED, mem->fd, 0); 196e5c31af7Sopenharmony_ci if (!mem->data) 197e5c31af7Sopenharmony_ci return -1; 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci return 0; 200e5c31af7Sopenharmony_ci} 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_civoid ipc_mem_close (ipc_sharedmemory* mem) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci if (mem->data != NULL) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci munmap(mem->data, mem->size); 207e5c31af7Sopenharmony_ci close(mem->fd); 208e5c31af7Sopenharmony_ci shm_unlink(mem->name); 209e5c31af7Sopenharmony_ci } 210e5c31af7Sopenharmony_ci free(mem->name); 211e5c31af7Sopenharmony_ci mem->name = NULL; 212e5c31af7Sopenharmony_ci mem->size = 0; 213e5c31af7Sopenharmony_ci} 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ciint ipc_sem_create (ipc_sharedsemaphore* sem, int initialvalue) 216e5c31af7Sopenharmony_ci{ 217e5c31af7Sopenharmony_ci sem->semaphore = sem_open(sem->name, O_CREAT, 0700, initialvalue); 218e5c31af7Sopenharmony_ci if (sem->semaphore == SEM_FAILED) 219e5c31af7Sopenharmony_ci return -1; 220e5c31af7Sopenharmony_ci return 0; 221e5c31af7Sopenharmony_ci} 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_civoid ipc_sem_close (ipc_sharedsemaphore* sem) 224e5c31af7Sopenharmony_ci{ 225e5c31af7Sopenharmony_ci sem_close(sem->semaphore); 226e5c31af7Sopenharmony_ci sem_unlink(sem->name); 227e5c31af7Sopenharmony_ci free(sem->name); 228e5c31af7Sopenharmony_ci} 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_civoid ipc_sem_increment (ipc_sharedsemaphore* sem) 231e5c31af7Sopenharmony_ci{ 232e5c31af7Sopenharmony_ci sem_post(sem->semaphore); 233e5c31af7Sopenharmony_ci} 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_civoid ipc_sem_decrement (ipc_sharedsemaphore* sem) 236e5c31af7Sopenharmony_ci{ 237e5c31af7Sopenharmony_ci sem_wait(sem->semaphore); 238e5c31af7Sopenharmony_ci} 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ciint ipc_sem_try_decrement(ipc_sharedsemaphore* sem) 241e5c31af7Sopenharmony_ci{ 242e5c31af7Sopenharmony_ci int res = sem_trywait(sem->semaphore); 243e5c31af7Sopenharmony_ci if (res == 0) 244e5c31af7Sopenharmony_ci return 1; 245e5c31af7Sopenharmony_ci return 0; 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci#endif // !_WIN32 249