Unstaged changes working on Android support
[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 // Moved this here from Thread.ec to make compiling ecereCOM in Debug easier
31 public int64 GetCurrentThreadID()
32 {
33 #if defined(__WIN32__)
34    return (int64)GetCurrentThreadId();
35 #else
36    return (int64)pthread_self();
37 #endif
38 }
39
40 public class Mutex : struct
41 {
42 //   class_fixed
43 #if defined(__WIN32__)
44 #ifdef _DEBUG
45    HANDLE mutex;
46 #else
47    CRITICAL_SECTION mutex;
48 #endif
49 #else
50    pthread_mutex_t mutex;
51 #endif
52
53 #ifdef _DEBUG
54    int64 owningThread;
55 #endif
56    int lockCount;
57
58    Mutex()
59    {
60 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
61 #ifdef _DEBUG
62       mutex = CreateMutex(null, FALSE, null);
63 #else
64       InitializeCriticalSection(&mutex);
65 #endif
66 #else
67       pthread_mutexattr_t attr;
68       pthread_mutexattr_init(&attr);
69
70       // settype is available on Linux now, and hopefully _GNU_SOURCE should ensure it is
71 #if 0 // def __linux__
72       pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
73 #else
74       pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
75 #endif
76
77       pthread_mutex_init(&mutex, &attr);
78       pthread_mutexattr_destroy(&attr);
79 #endif
80       lockCount = 0;
81 #ifdef _DEBUG
82       owningThread = 0;
83 #endif
84       return true;
85    }
86
87    ~Mutex()
88    {
89 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
90 #ifdef _DEBUG
91       CloseHandle(mutex);
92 #else
93       DeleteCriticalSection(&mutex);
94 #endif
95 #else
96       pthread_mutex_destroy(&mutex);
97 #endif
98    }
99
100 public:
101    void Wait(void)
102    {
103       if(this)
104       {
105          /*
106          if(this == globalSystem.fileMonitorMutex)
107             printf("[%d] Waiting on Mutex %x\n", (int)GetCurrentThreadID(), this);
108          */
109 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
110 #ifdef _DEBUG
111          if(WaitForSingleObject(mutex, INFINITE /*2000*/) == WAIT_TIMEOUT)
112             PrintLn("Deadlock?");
113 #else
114          EnterCriticalSection(&mutex);
115 #endif
116 #else
117 #ifdef _DEBUG
118          {
119             int e;
120             e = pthread_mutex_lock(&mutex);
121             if(e)
122                PrintLn("pthread_mutex_lock returned ", e);
123          }
124 #else
125          pthread_mutex_lock(&mutex);
126 #endif
127 #endif
128
129 #ifdef _DEBUG
130          owningThread = GetCurrentThreadID();
131 #endif
132          lockCount++;
133       }
134    }
135
136    void Release(void)
137    {
138       if(this)
139       {
140          /*
141          if(this == globalSystem.fileMonitorMutex)
142             printf("[%d] Releasing Mutex %x\n", (int)GetCurrentThreadID(), this);
143          */
144 #ifdef _DEBUG
145          if(lockCount && owningThread != GetCurrentThreadID())
146             PrintLn("WARNING: Not in owning thread!!");
147 #endif
148
149          if(!--lockCount)
150 #ifdef _DEBUG
151             owningThread = 0;
152 #else
153             ;
154 #endif
155 #if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
156 #ifdef _DEBUG
157          ReleaseMutex(mutex);
158 #else
159          LeaveCriticalSection(&mutex);
160 #endif
161 #else
162 #ifdef _DEBUG
163          {
164             int e;
165             e = pthread_mutex_unlock(&mutex);
166             if(e)
167                PrintLn("pthread_mutex_unlock returned ", e);
168          }
169 #else
170          pthread_mutex_unlock(&mutex);
171 #endif
172 #endif
173 #ifdef _DEBUG
174          if(lockCount < 0)
175             PrintLn("WARNING: lockCount < 0");
176 #endif
177       }
178    }
179
180    property int lockCount { get { return lockCount; } }
181 };