• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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