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