ecere/ECON: Fixed ECON parser expecting members in specific order
[sdk] / ecere / src / sys / Semaphore.ec
1 #define _Noreturn
2
3 default:
4 #include <errno.h>
5 private:
6
7 namespace sys;
8
9 #define uint _uint
10 // Platform includes
11 #if defined(__WIN32__)
12 #define WIN32_LEAN_AND_MEAN
13 #define String String_
14 #include <windows.h>
15 #undef String
16 #elif defined(__APPLE__)
17 #define set _set
18 #include <mach/mach.h>
19 #include <mach/task.h>
20 #include <mach/semaphore.h>
21 #undef set
22 #else
23 #include <semaphore.h>
24 #endif
25 #undef uint
26
27 import "System"
28
29 public class Semaphore : struct
30 {
31 #if !defined(__EMSCRIPTEN__)
32
33 #if defined(__WIN32__)
34    HANDLE handle;
35 #elif defined(__APPLE__)
36    semaphore_t semaphore;
37    int count;
38    Mutex mutex { };
39 #else
40    sem_t semaphore;
41 #endif
42 #endif
43
44    int initCount, maxCount;
45
46    Semaphore()
47    {
48 #if !defined(__EMSCRIPTEN__)
49 #if defined(__WIN32__)
50       handle = CreateSemaphore(null, 0, 1, null);
51 #elif defined(__APPLE__)
52       semaphore_create(mach_task_self(), &semaphore, SYNC_POLICY_FIFO, 0);
53 #else
54       sem_init(&semaphore, 0, 0);
55 #endif
56 #endif
57       maxCount = 1;
58       initCount = 0;
59    }
60
61    ~Semaphore()
62    {
63 #if !defined(__EMSCRIPTEN__)
64 #if defined(__WIN32__)
65       if(handle) CloseHandle(handle);
66 #elif defined(__APPLE__)
67       semaphore_destroy(mach_task_self(), semaphore);
68 #else
69       sem_destroy(&semaphore);
70 #endif
71 #endif
72    }
73
74 public:
75    bool TryWait(void)
76    {
77       bool result;
78 #if !defined(__EMSCRIPTEN__)
79 #if defined(__WIN32__)
80       result = WaitForSingleObject(handle, 0) != WAIT_TIMEOUT;
81 #elif defined(__APPLE__)
82       bool wait = false;
83       mutex.Wait();
84       result = false;
85       if(count > 0)
86       {
87          count--;
88          wait = true;
89          result = true;
90       }
91       mutex.Release();
92       if(wait)
93          semaphore_wait(semaphore);
94 #else
95       result = sem_trywait(&semaphore) != EAGAIN;
96 #endif
97 #endif
98       return result;
99    }
100
101    void Wait(void)
102    {
103 #if !defined(__EMSCRIPTEN__)
104 #if defined(__WIN32__)
105       if(WaitForSingleObject(handle, INFINITE /*2000*/) == WAIT_TIMEOUT)
106          PrintLn("Semaphore not released?");
107 #elif defined(__APPLE__)
108       mutex.Wait();
109       count--;
110       mutex.Release();
111       semaphore_wait(semaphore);
112 #else
113 #ifdef _DEBUG
114       while(true)
115       {
116          if(!sem_wait(&semaphore) || errno != EINTR)
117             break;
118       }
119 #else
120       sem_wait(&semaphore);
121 #endif
122 #endif
123 #endif
124    }
125
126    void Release(void)
127    {
128 #if !defined(__EMSCRIPTEN__)
129 #if defined(__WIN32__)
130       ReleaseSemaphore(handle, 1, null);
131 #elif defined(__APPLE__)
132       mutex.Wait();
133       count++;
134       mutex.Release();
135       semaphore_signal(semaphore);
136 #else
137       int count;
138       sem_getvalue(&semaphore, &count);
139       if(count < maxCount)
140          sem_post(&semaphore);
141 #endif
142 #endif
143    }
144
145    property int initCount
146    {
147       set
148       {
149 #if !defined(__EMSCRIPTEN__)
150 #if defined(__WIN32__)
151          if(handle) CloseHandle(handle);
152          handle = CreateSemaphore(null, initCount, value, null);
153 #elif defined(__APPLE__)
154          semaphore_destroy(mach_task_self(), semaphore);
155          semaphore_create(mach_task_self(), &semaphore, SYNC_POLICY_FIFO, 0);
156          count = value;
157 #else
158          sem_destroy(&semaphore);
159          sem_init(&semaphore, 0, initCount);
160 #endif
161 #endif
162          initCount = value;
163       }
164       get { return initCount; }
165    };
166    property int maxCount
167    {
168       set
169       {
170 #if !defined(__EMSCRIPTEN__)
171 #if defined(__WIN32__)
172          if(handle) CloseHandle(handle);
173          handle = CreateSemaphore(null, value, maxCount, null);
174 #endif
175 #endif
176          maxCount = value;
177       }
178       get { return maxCount; }
179    };
180 };