ecere,ecereCOM: support Emscriptem platform. add new Emscripten interface driver.
[sdk] / ecere / src / sys / Mutex.ec
1
2 #if defined(__ANDROID__)
3 #include <android/log.h>
4
5 #define printf(...)  ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
6 #endif
7
8 namespace sys;
9
10 #undef _GNU_SOURCE
11 #undef __USE_UNIX98
12 #define _GNU_SOURCE
13 #define __USE_UNIX98
14 // Platform includes
15 #define uint _uint
16 #define set _set
17 #define String _String
18 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
19 #define WIN32_LEAN_AND_MEAN
20 #include <windows.h>
21 #else
22 #include <pthread.h>
23 #endif
24 #undef uint
25 #undef set
26 #undef String
27
28 import "instance"
29
30 #if !defined(__EMSCRIPTEN__)
31
32 // Moved this here from Thread.ec to make compiling ecereCOM in Debug easier
33 public int64 GetCurrentThreadID()
34 {
35 #if defined(__WIN32__)
36    return (int64)GetCurrentThreadId();
37 #else
38    return (int64)pthread_self();
39 #endif
40 }
41
42 public class Mutex : struct
43 {
44 //   class_fixed
45 #if defined(__WIN32__)
46 #ifdef _DEBUG
47    HANDLE mutex;
48 #else
49    CRITICAL_SECTION mutex;
50 #endif
51 #else
52    pthread_mutex_t mutex;
53 #endif
54
55 #ifdef _DEBUG
56    int64 owningThread;
57 #endif
58    int lockCount;
59
60    Mutex()
61    {
62 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
63 #ifdef _DEBUG
64       mutex = CreateMutex(null, FALSE, null);
65 #else
66       InitializeCriticalSection(&mutex);
67 #endif
68 #else
69       pthread_mutexattr_t attr;
70       pthread_mutexattr_init(&attr);
71
72       // settype is available on Linux now, and hopefully _GNU_SOURCE should ensure it is
73 #if 0 // def __linux__
74       pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
75 #else
76       pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
77 #endif
78
79       pthread_mutex_init(&mutex, &attr);
80       pthread_mutexattr_destroy(&attr);
81 #endif
82       lockCount = 0;
83 #ifdef _DEBUG
84       owningThread = 0;
85 #endif
86       return true;
87    }
88
89    ~Mutex()
90    {
91 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
92 #ifdef _DEBUG
93       CloseHandle(mutex);
94 #else
95       DeleteCriticalSection(&mutex);
96 #endif
97 #else
98       pthread_mutex_destroy(&mutex);
99 #endif
100    }
101
102 public:
103    void Wait(void)
104    {
105       if(this)
106       {
107          /*
108          if(this == globalSystem.fileMonitorMutex)
109             printf("[%d] Waiting on Mutex %x\n", (int)GetCurrentThreadID(), this);
110          */
111 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
112 #ifdef _DEBUG
113          if(WaitForSingleObject(mutex, INFINITE /*2000*/) == WAIT_TIMEOUT)
114             PrintLn("Deadlock?");
115 #else
116          EnterCriticalSection(&mutex);
117 #endif
118 #else
119 #ifdef _DEBUG
120          {
121             int e;
122             e = pthread_mutex_lock(&mutex);
123             if(e)
124                PrintLn("pthread_mutex_lock returned ", e);
125          }
126 #else
127          pthread_mutex_lock(&mutex);
128 #endif
129 #endif
130
131 #ifdef _DEBUG
132          owningThread = GetCurrentThreadID();
133 #endif
134          lockCount++;
135       }
136    }
137
138    void Release(void)
139    {
140       if(this)
141       {
142          /*
143          if(this == globalSystem.fileMonitorMutex)
144             printf("[%d] Releasing Mutex %x\n", (int)GetCurrentThreadID(), this);
145          */
146 #ifdef _DEBUG
147          if(lockCount && owningThread != GetCurrentThreadID())
148             PrintLn("WARNING: Not in owning thread!!");
149 #endif
150
151          if(!--lockCount)
152 #ifdef _DEBUG
153             owningThread = 0;
154 #else
155             ;
156 #endif
157 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
158 #ifdef _DEBUG
159          ReleaseMutex(mutex);
160 #else
161          LeaveCriticalSection(&mutex);
162 #endif
163 #else
164 #ifdef _DEBUG
165          {
166             int e;
167             e = pthread_mutex_unlock(&mutex);
168             if(e)
169                PrintLn("pthread_mutex_unlock returned ", e);
170          }
171 #else
172          pthread_mutex_unlock(&mutex);
173 #endif
174 #endif
175 #ifdef _DEBUG
176          if(lockCount < 0)
177             PrintLn("WARNING: lockCount < 0");
178 #endif
179       }
180    }
181
182    property int lockCount { get { return lockCount; } }
183 };
184
185 #endif // !defined(__EMSCRIPTEN__)