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