1 /*
2 * Copyright (C) 2010-2011 x264 project
3 *
4 * Authors: Steven Walters <kemuri9@gmail.com>
5 * Pegasys Inc. <http://www.pegasys-inc.com>
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * @file
26 * w32threads to pthreads wrapper
27 */
28
29 #ifndef FFMPEG_COMPAT_W32PTHREADS_H
30 #define FFMPEG_COMPAT_W32PTHREADS_H
31
32 /* Build up a pthread-like API using underlying Windows API. Have only static
33 * methods so as to not conflict with a potentially linked in pthread-win32
34 * library.
35 * As most functions here are used without checking return values,
36 * only implement return values as necessary. */
37
38 #define WIN32_LEAN_AND_MEAN
39 #include <windows.h>
40 #include <process.h>
41
46
49 void *(*func)(
void*
arg);
53
54 /* the conditional variable api for windows 6.0+ uses critical sections and
55 * not mutexes */
57
58 /* This is the CONDITION_VARIABLE typedef for using Windows' native
59 * conditional variables on kernels 6.0+. */
60 #if HAVE_CONDITION_VARIABLE_PTR
62 #else
66 #endif
67
68 #if _WIN32_WINNT >= 0x0600
69 #define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
70 #define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
71 #endif
72
74 {
77 return 0;
78 }
79
81 void *(*start_routine)(
void*),
void *
arg)
82 {
83 thread->
func = start_routine;
88 }
89
91 {
93 if (ret != WAIT_OBJECT_0)
94 return;
95 if (value_ptr)
96 *value_ptr = thread.
ret;
97 CloseHandle(thread.
handle);
98 }
99
101 {
102 InitializeCriticalSection(m);
103 return 0;
104 }
106 {
107 DeleteCriticalSection(m);
108 return 0;
109 }
111 {
112 EnterCriticalSection(m);
113 return 0;
114 }
116 {
117 LeaveCriticalSection(m);
118 return 0;
119 }
120
121 #if _WIN32_WINNT >= 0x0600
123 {
124 InitializeConditionVariable(cond);
125 return 0;
126 }
127
128 /* native condition variables do not destroy */
130 {
131 return;
132 }
133
135 {
136 WakeAllConditionVariable(cond);
137 }
138
140 {
141 SleepConditionVariableCS(cond, mutex, INFINITE);
142 return 0;
143 }
144
146 {
147 WakeConditionVariable(cond);
148 }
149
150 #else // _WIN32_WINNT < 0x0600
151 /* for pre-Windows 6.0 platforms we need to define and use our own condition
152 * variable and api */
161
162 /* function pointers to conditional variable API on windows 6.0+ kernels */
168
170 {
172 if (cond_init) {
173 cond_init(cond);
174 return 0;
175 }
176
177 /* non native condition variables */
179 if (!win32_cond)
180 return ENOMEM;
181 cond->
Ptr = win32_cond;
184 return ENOMEM;
187 return ENOMEM;
188
191 return 0;
192 }
193
195 {
197 /* native condition variables do not destroy */
198 if (cond_init)
199 return;
200
201 /* non native condition variables */
208 }
209
211 {
213 int have_waiter;
214
215 if (cond_broadcast) {
216 cond_broadcast(cond);
217 return;
218 }
219
220 /* non native condition variables */
223 have_waiter = 0;
224
227 have_waiter = 1;
228 }
229
230 if (have_waiter) {
233 WaitForSingleObject(win32_cond->
waiters_done, INFINITE);
236 } else
239 }
240
242 {
244 int last_waiter;
245 if (cond_wait) {
246 cond_wait(cond, mutex, INFINITE);
247 return 0;
248 }
249
250 /* non native condition variables */
256
257 // unlock the external mutex
259 WaitForSingleObject(win32_cond->
semaphore, INFINITE);
260
265
266 if (last_waiter)
268
269 // lock the external mutex
271 }
272
274 {
276 int have_waiter;
277 if (cond_signal) {
278 cond_signal(cond);
279 return;
280 }
281
283
284 /* non-native condition variables */
288
289 if (have_waiter) {
291 WaitForSingleObject(win32_cond->
waiters_done, INFINITE);
293 }
294
296 }
297 #endif
298
300 {
301 #if _WIN32_WINNT < 0x0600
302 HANDLE kernel_dll = GetModuleHandle(TEXT(
"kernel32.dll"));
303 /* if one is available, then they should all be available */
304 cond_init =
306 cond_broadcast =
308 cond_signal =
310 cond_wait =
312 #endif
313
314 }
315
316 #endif /* FFMPEG_COMPAT_W32PTHREADS_H */