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