This source file includes following definitions.
- glwthread_timedmutex_init
- glwthread_timedmutex_lock
- glwthread_timedmutex_trylock
- glwthread_timedmutex_timedlock
- glwthread_timedmutex_unlock
- glwthread_timedmutex_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-timedmutex.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_timedmutex_init (glwthread_timedmutex_t *mutex)
35 {
36
37
38
39 HANDLE event = CreateEvent (NULL, FALSE, FALSE, NULL);
40 if (event == INVALID_HANDLE_VALUE)
41 return EAGAIN;
42 mutex->event = event;
43 InitializeCriticalSection (&mutex->lock);
44 mutex->guard.done = 1;
45 return 0;
46 }
47
48 int
49 glwthread_timedmutex_lock (glwthread_timedmutex_t *mutex)
50 {
51 if (!mutex->guard.done)
52 {
53 if (InterlockedIncrement (&mutex->guard.started) == 0)
54 {
55
56
57 int err = glwthread_timedmutex_init (mutex);
58 if (err != 0)
59 {
60
61 InterlockedDecrement (&mutex->guard.started);
62 return err;
63 }
64 }
65 else
66 {
67
68 InterlockedDecrement (&mutex->guard.started);
69
70
71 while (!mutex->guard.done)
72 Sleep (0);
73 }
74 }
75 EnterCriticalSection (&mutex->lock);
76 return 0;
77 }
78
79 int
80 glwthread_timedmutex_trylock (glwthread_timedmutex_t *mutex)
81 {
82 if (!mutex->guard.done)
83 {
84 if (InterlockedIncrement (&mutex->guard.started) == 0)
85 {
86
87
88 int err = glwthread_timedmutex_init (mutex);
89 if (err != 0)
90 {
91
92 InterlockedDecrement (&mutex->guard.started);
93 return err;
94 }
95 }
96 else
97 {
98
99 InterlockedDecrement (&mutex->guard.started);
100
101
102 return EBUSY;
103 }
104 }
105 if (!TryEnterCriticalSection (&mutex->lock))
106 return EBUSY;
107 return 0;
108 }
109
110 int
111 glwthread_timedmutex_timedlock (glwthread_timedmutex_t *mutex,
112 const struct timespec *abstime)
113 {
114 if (!mutex->guard.done)
115 {
116 if (InterlockedIncrement (&mutex->guard.started) == 0)
117 {
118
119
120 int err = glwthread_timedmutex_init (mutex);
121 if (err != 0)
122 {
123
124 InterlockedDecrement (&mutex->guard.started);
125 return err;
126 }
127 }
128 else
129 {
130
131 InterlockedDecrement (&mutex->guard.started);
132
133
134 while (!mutex->guard.done)
135 Sleep (0);
136 }
137 }
138
139
140
141
142
143
144
145 for (;;)
146 {
147 if (TryEnterCriticalSection (&mutex->lock))
148 break;
149
150 {
151 struct timeval currtime;
152 DWORD timeout;
153 DWORD result;
154
155 gettimeofday (&currtime, NULL);
156
157
158
159 if (currtime.tv_sec > abstime->tv_sec)
160 timeout = 0;
161 else
162 {
163 unsigned long seconds = abstime->tv_sec - currtime.tv_sec;
164 timeout = seconds * 1000;
165 if (timeout / 1000 != seconds)
166 timeout = INFINITE;
167 else
168 {
169 long milliseconds =
170 abstime->tv_nsec / 1000000 - currtime.tv_usec / 1000;
171 if (milliseconds >= 0)
172 {
173 timeout += milliseconds;
174 if (timeout < milliseconds)
175 timeout = INFINITE;
176 }
177 else
178 {
179 if (timeout >= - milliseconds)
180 timeout -= (- milliseconds);
181 else
182 timeout = 0;
183 }
184 }
185 }
186 if (timeout == 0)
187 return ETIMEDOUT;
188
189
190
191 result = WaitForSingleObject (mutex->event, timeout);
192 if (result == WAIT_FAILED)
193 abort ();
194 if (result == WAIT_TIMEOUT)
195 return ETIMEDOUT;
196
197
198 }
199 }
200 return 0;
201 }
202
203 int
204 glwthread_timedmutex_unlock (glwthread_timedmutex_t *mutex)
205 {
206 if (!mutex->guard.done)
207 return EINVAL;
208 LeaveCriticalSection (&mutex->lock);
209
210
211
212 SetEvent (mutex->event);
213 return 0;
214 }
215
216 int
217 glwthread_timedmutex_destroy (glwthread_timedmutex_t *mutex)
218 {
219 if (!mutex->guard.done)
220 return EINVAL;
221 DeleteCriticalSection (&mutex->lock);
222
223
224 CloseHandle (mutex->event);
225 mutex->guard.done = 0;
226 return 0;
227 }