This source file includes following definitions.
- glwthread_timedrecmutex_init
- glwthread_timedrecmutex_lock
- glwthread_timedrecmutex_trylock
- glwthread_timedrecmutex_timedlock
- glwthread_timedrecmutex_unlock
- glwthread_timedrecmutex_destroy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22
23 #include "windows-timedrecmutex.h"
24
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <sys/time.h>
28
29
30 #undef CreateEvent
31 #define CreateEvent CreateEventA
32
33 int
34 glwthread_timedrecmutex_init (glwthread_timedrecmutex_t *mutex)
35 {
36 mutex->owner = 0;
37 mutex->depth = 0;
38
39
40
41 HANDLE event = CreateEvent (NULL, FALSE, FALSE, NULL);
42 if (event == INVALID_HANDLE_VALUE)
43 return EAGAIN;
44 mutex->event = event;
45 InitializeCriticalSection (&mutex->lock);
46 mutex->guard.done = 1;
47 return 0;
48 }
49
50 int
51 glwthread_timedrecmutex_lock (glwthread_timedrecmutex_t *mutex)
52 {
53 if (!mutex->guard.done)
54 {
55 if (InterlockedIncrement (&mutex->guard.started) == 0)
56 {
57
58
59 int err = glwthread_timedrecmutex_init (mutex);
60 if (err != 0)
61 {
62
63 InterlockedDecrement (&mutex->guard.started);
64 return err;
65 }
66 }
67 else
68 {
69
70 InterlockedDecrement (&mutex->guard.started);
71
72
73 while (!mutex->guard.done)
74 Sleep (0);
75 }
76 }
77 {
78 DWORD self = GetCurrentThreadId ();
79 if (mutex->owner != self)
80 {
81 EnterCriticalSection (&mutex->lock);
82 mutex->owner = self;
83 }
84 if (++(mutex->depth) == 0)
85 {
86 mutex->depth--;
87 return EAGAIN;
88 }
89 }
90 return 0;
91 }
92
93 int
94 glwthread_timedrecmutex_trylock (glwthread_timedrecmutex_t *mutex)
95 {
96 if (!mutex->guard.done)
97 {
98 if (InterlockedIncrement (&mutex->guard.started) == 0)
99 {
100
101
102 int err = glwthread_timedrecmutex_init (mutex);
103 if (err != 0)
104 {
105
106 InterlockedDecrement (&mutex->guard.started);
107 return err;
108 }
109 }
110 else
111 {
112
113 InterlockedDecrement (&mutex->guard.started);
114
115
116 return EBUSY;
117 }
118 }
119 {
120 DWORD self = GetCurrentThreadId ();
121 if (mutex->owner != self)
122 {
123 if (!TryEnterCriticalSection (&mutex->lock))
124 return EBUSY;
125 mutex->owner = self;
126 }
127 if (++(mutex->depth) == 0)
128 {
129 mutex->depth--;
130 return EAGAIN;
131 }
132 }
133 return 0;
134 }
135
136 int
137 glwthread_timedrecmutex_timedlock (glwthread_timedrecmutex_t *mutex,
138 const struct timespec *abstime)
139 {
140 if (!mutex->guard.done)
141 {
142 if (InterlockedIncrement (&mutex->guard.started) == 0)
143 {
144
145
146 int err = glwthread_timedrecmutex_init (mutex);
147 if (err != 0)
148 {
149
150 InterlockedDecrement (&mutex->guard.started);
151 return err;
152 }
153 }
154 else
155 {
156
157 InterlockedDecrement (&mutex->guard.started);
158
159
160 while (!mutex->guard.done)
161 Sleep (0);
162 }
163 }
164
165 {
166 DWORD self = GetCurrentThreadId ();
167 if (mutex->owner != self)
168 {
169
170
171
172
173
174
175 for (;;)
176 {
177 if (TryEnterCriticalSection (&mutex->lock))
178 break;
179
180 {
181 struct timeval currtime;
182 DWORD timeout;
183 DWORD result;
184
185 gettimeofday (&currtime, NULL);
186
187
188
189 if (currtime.tv_sec > abstime->tv_sec)
190 timeout = 0;
191 else
192 {
193 unsigned long seconds = abstime->tv_sec - currtime.tv_sec;
194 timeout = seconds * 1000;
195 if (timeout / 1000 != seconds)
196 timeout = INFINITE;
197 else
198 {
199 long milliseconds =
200 abstime->tv_nsec / 1000000 - currtime.tv_usec / 1000;
201 if (milliseconds >= 0)
202 {
203 timeout += milliseconds;
204 if (timeout < milliseconds)
205 timeout = INFINITE;
206 }
207 else
208 {
209 if (timeout >= - milliseconds)
210 timeout -= (- milliseconds);
211 else
212 timeout = 0;
213 }
214 }
215 }
216 if (timeout == 0)
217 return ETIMEDOUT;
218
219
220
221 result = WaitForSingleObject (mutex->event, timeout);
222 if (result == WAIT_FAILED)
223 abort ();
224 if (result == WAIT_TIMEOUT)
225 return ETIMEDOUT;
226
227
228 }
229 }
230 mutex->owner = self;
231 }
232 if (++(mutex->depth) == 0)
233 {
234 mutex->depth--;
235 return EAGAIN;
236 }
237 }
238 return 0;
239 }
240
241 int
242 glwthread_timedrecmutex_unlock (glwthread_timedrecmutex_t *mutex)
243 {
244 if (mutex->owner != GetCurrentThreadId ())
245 return EPERM;
246 if (mutex->depth == 0)
247 return EINVAL;
248 if (--(mutex->depth) == 0)
249 {
250 mutex->owner = 0;
251 LeaveCriticalSection (&mutex->lock);
252
253
254
255 SetEvent (mutex->event);
256 }
257 return 0;
258 }
259
260 int
261 glwthread_timedrecmutex_destroy (glwthread_timedrecmutex_t *mutex)
262 {
263 if (mutex->owner != 0)
264 return EBUSY;
265 DeleteCriticalSection (&mutex->lock);
266
267
268 CloseHandle (mutex->event);
269 mutex->guard.done = 0;
270 return 0;
271 }