1 krisbash 1.1 #ifndef _pal_sem_h
2 #define _pal_sem_h
3
4 #include <nits/base/nits.h>
5
6 #if defined(PAL_HAVE_POSIX)
7 # include <fcntl.h>
8 # include <sys/stat.h>
9 # include <semaphore.h>
10 # include <time.h>
11 #endif
12
13 PAL_BEGIN_EXTERNC
14
15 /*
16 **==============================================================================
17 **
18 ** Sem - semaphore
19 **
20 **==============================================================================
21 */
22 krisbash 1.1
23 typedef struct _Sem
24 {
25 #if defined(_MSC_VER)
26 HANDLE handle;
27 #else
28 sem_t* sem;
29 #endif
30 }
31 Sem;
32
33 typedef enum _SemUserAccess
34 {
35 SEM_USER_ACCESS_DEFAULT = 1,
36 SEM_USER_ACCESS_ALLOW_ALL = 2
37 }
38 SemUserAccess;
39
40 _Success_(return == 0) int Sem_Init_Injected(
41 _Out_ Sem* self,
42 SemUserAccess userAccess,
43 krisbash 1.1 unsigned int count,
44 NitsCallSite cs);
45
46 #define Sem_Init(self, userAccess, count) Sem_Init_Injected(self, userAccess, count, NitsHere())
47
48 PAL_INLINE void Sem_Destroy(
49 _Inout_ Sem* self)
50 {
51 #if defined(_MSC_VER)
52 CloseHandle(self->handle);
53 #else
54 if (self->sem)
55 {
56 sem_close(self->sem);
57 PAL_Free(self->sem);
58 self->sem = NULL;
59 }
60 #endif
61 }
62
63 PAL_INLINE int Sem_Wait(
64 krisbash 1.1 _Inout_ Sem* self)
65 {
66 #if defined(_MSC_VER)
67 return WaitForSingleObject(self->handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
68 #else
69 return sem_wait(self->sem) == 0 ? 0 : -1;
70 #endif
71 }
72
73 #if !defined(CONFIG_HAVE_SEM_TIMEDWAIT)
74 #include <errno.h>
75 #include <pal/sleep.h>
76
77 int __TimedWaitHelper(sem_t* sem, int milliseconds);
78 #endif
79
80 PAL_INLINE int Sem_TimedWait(
81 _Inout_ Sem* self,
82 int milliseconds)
83 {
84 #if defined(_MSC_VER)
85 krisbash 1.1 return WaitForSingleObject(self->handle, milliseconds) == WAIT_OBJECT_0 ? 0 : -1;
86 #elif defined(CONFIG_HAVE_SEM_TIMEDWAIT)
87 struct timespec temp =
88 {
89 time(0) + milliseconds / 1000,
90 milliseconds % 1000 * 1000000
91 };
92 return sem_timedwait(self->sem, &temp) == 0 ? 0 : -1;
93 #else
94 return __TimedWaitHelper(self->sem, milliseconds);
95 #endif
96 }
97
98 int Sem_Post(
99 _Inout_ Sem* self,
100 unsigned int count);
101
102 /*
103 **==============================================================================
104 **
105 ** NamedSem - named semaphore
106 krisbash 1.1 **
107 **==============================================================================
108 */
109
110 #define NAMEDSEM_FLAG_CREATE 1
111 #define NAMEDSEM_FLAG_EXCLUSIVE 2
112
113 typedef struct _NamedSem
114 {
115 #if defined(_MSC_VER)
116 HANDLE handle;
117 #else
118 sem_t* sem;
119 char semname[PAL_MAX_PATH_SIZE];
120 #endif
121 }
122 NamedSem;
123
124 _Return_type_success_(return == 0) int NamedSem_Open_Injected(
125 _Out_ NamedSem* self,
126 SemUserAccess userAccess,
127 krisbash 1.1 unsigned int count,
128 _In_z_ const PAL_Char *name,
129 unsigned long flags,
130 NitsCallSite cs);
131
132 #define NamedSem_Open(self, userAccess, count, name, flags) NamedSem_Open_Injected(self, userAccess, count, name, flags, NitsHere())
133
134 void NamedSem_Close(
135 _Inout_ NamedSem* self);
136
137 PAL_INLINE int NamedSem_Wait(
138 _Inout_ NamedSem* self)
139 {
140 #if defined(_MSC_VER)
141 return WaitForSingleObject(self->handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
142 #else
143 return sem_wait(self->sem) == 0 ? 0 : -1;
144 #endif
145 }
146
147 /*
148 krisbash 1.1 * To be called when the semaphore is no longer needed by any user of the semaphore
149 */
150 PAL_INLINE void NamedSem_Destroy(
151 _Inout_ NamedSem* self)
152 {
153 #if defined(_MSC_VER)
154
155 #else
156 sem_unlink(self->semname);
157 #endif
158 }
159
160 PAL_INLINE int NamedSem_TimedWait(
161 _Inout_ NamedSem* self,
162 int milliseconds)
163 {
164 #if defined(_MSC_VER)
165 return WaitForSingleObject(self->handle, milliseconds) == WAIT_OBJECT_0 ? 0 : -1;
166 #elif defined(CONFIG_HAVE_SEM_TIMEDWAIT)
167 struct timespec temp =
168 {
169 krisbash 1.1 time(0) + milliseconds / 1000,
170 milliseconds % 1000 * 1000000
171 };
172 return sem_timedwait(self->sem, &temp) == 0 ? 0 : -1;
173 #else
174 return __TimedWaitHelper(self->sem, milliseconds);
175 #endif
176 }
177
178 int NamedSem_Post(
179 _Inout_ NamedSem* self,
180 unsigned int count);
181
182 PAL_INLINE int NamedSem_GetValue(
183 _Inout_ NamedSem* self,
184 _Out_ int *value)
185 {
186 #if defined(_MSC_VER)
187 *value = 0;
188 return 0;
189 #else
190 krisbash 1.1 return sem_getvalue(self->sem, value) == 0 ? 0 : -1;
191 #endif
192 }
193
194 PAL_END_EXTERNC
195
196 #endif /* _pal_sem_h */
|