1 krisbash 1.1 #ifndef _pal_sem_h
2 #define _pal_sem_h
3
4 #include <nits/base/nits.h>
5 #include <stdio.h>
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 #ifndef __MSC_VER
14 # ifndef SEM_FAILED
15 # define SEM_FAILED (sem_t*)-1
16 # endif
17 #endif
18
19 PAL_BEGIN_EXTERNC
20
21 /*
22 krisbash 1.1 **==============================================================================
23 **
24 ** Sem - semaphore
25 **
26 **==============================================================================
27 */
28
29 typedef struct _Sem
30 {
31 #if defined(_MSC_VER)
32 HANDLE handle;
33 #else
34 sem_t* sem;
35 #endif
36 }
37 Sem;
38
39 typedef enum _SemUserAccess
40 {
41 SEM_USER_ACCESS_DEFAULT = 1,
42 SEM_USER_ACCESS_ALLOW_ALL = 2
43 krisbash 1.1 }
44 SemUserAccess;
45
46 _Success_(return == 0) int Sem_Init_Injected(
47 _Out_ Sem* self,
48 SemUserAccess userAccess,
49 unsigned int count,
50 NitsCallSite cs);
51
52 #define Sem_Init(self, userAccess, count) Sem_Init_Injected(self, userAccess, count, NitsHere())
53
54 PAL_INLINE void Sem_Destroy(
55 _Inout_ Sem* self)
56 {
57 #if defined(_MSC_VER)
58 CloseHandle(self->handle);
59 #else
60 if (self->sem)
61 {
62 sem_close(self->sem);
63 free(self->sem);
64 krisbash 1.1 self->sem = NULL;
65 }
66 #endif
67 }
68
69 PAL_INLINE int Sem_Wait(
70 _Inout_ Sem* self)
71 {
72 #if defined(_MSC_VER)
73 return WaitForSingleObject(self->handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
74 #else
75 return sem_wait(self->sem) == 0 ? 0 : -1;
76 #endif
77 }
78
79 #if !defined(CONFIG_HAVE_SEM_TIMEDWAIT)
80 #include <errno.h>
81 #include <pal/sleep.h>
82
83 int __TimedWaitHelper(sem_t* sem, int milliseconds);
84 #endif
85 krisbash 1.1
86 PAL_INLINE int Sem_TimedWait(
87 _Inout_ Sem* self,
88 int milliseconds)
89 {
90 #if defined(_MSC_VER)
91 return WaitForSingleObject(self->handle, milliseconds) == WAIT_OBJECT_0 ? 0 : -1;
92 #elif defined(CONFIG_HAVE_SEM_TIMEDWAIT)
93 struct timespec temp =
94 {
95 time(0) + milliseconds / 1000,
96 milliseconds % 1000 * 1000000
97 };
98 return sem_timedwait(self->sem, &temp) == 0 ? 0 : -1;
99 #else
100 return __TimedWaitHelper(self->sem, milliseconds);
101 #endif
102 }
103
104 int Sem_Post(
105 _Inout_ Sem* self,
106 krisbash 1.1 unsigned int count);
|