Imported Upstream version 1.4
[deb_x265.git] / source / common / winxp.cpp
CommitLineData
72b9787e
JB
1/*****************************************************************************
2 * Copyright (C) 2013 x265 project
3 *
4 * Authors: Steve Borho <steve@borho.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19 *
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com
22 *****************************************************************************/
23
24#include "threading.h"
25
26#if defined(_WIN32) && (_WIN32_WINNT < 0x0600) // _WIN32_WINNT_VISTA
27
28namespace x265 {
29/* Mimic CONDITION_VARIABLE functions only supported on Vista+ */
30
31int WINAPI cond_init(ConditionVariable *cond)
32{ // InitializeConditionVariable
33 cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
34 if (!cond->semaphore)
35 return -1;
36 cond->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
37 if (!cond->waitersDone)
38 return -1;
39
40 InitializeCriticalSection(&cond->waiterCountMutex);
41 InitializeCriticalSection(&cond->broadcastMutex);
42 cond->waiterCount = 0;
43 cond->bIsBroadcast = false;
44
45 return 0;
46}
47
48void WINAPI cond_broadcast(ConditionVariable *cond)
49{ // WakeAllConditionVariable
50 EnterCriticalSection(&cond->broadcastMutex);
51 EnterCriticalSection(&cond->waiterCountMutex);
52 int haveWaiter = 0;
53
54 if (cond->waiterCount)
55 {
56 cond->bIsBroadcast = 1;
57 haveWaiter = 1;
58 }
59
60 if (haveWaiter)
61 {
62 ReleaseSemaphore(cond->semaphore, cond->waiterCount, NULL);
63 LeaveCriticalSection(&cond->waiterCountMutex);
64 WaitForSingleObject(cond->waitersDone, INFINITE);
65 cond->bIsBroadcast = 0;
66 }
67 else
68 LeaveCriticalSection(&cond->waiterCountMutex);
69
70 LeaveCriticalSection(&cond->broadcastMutex);
71}
72
73void WINAPI cond_signal(ConditionVariable *cond)
74{ // WakeConditionVariable
75 EnterCriticalSection(&cond->broadcastMutex);
76 EnterCriticalSection(&cond->waiterCountMutex);
77 int haveWaiter = cond->waiterCount;
78 LeaveCriticalSection(&cond->waiterCountMutex);
79
80 if (haveWaiter)
81 {
82 ReleaseSemaphore(cond->semaphore, 1, NULL);
83 WaitForSingleObject(cond->waitersDone, INFINITE);
84 }
85
86 LeaveCriticalSection(&cond->broadcastMutex);
87}
88
89BOOL WINAPI cond_wait(ConditionVariable *cond, CRITICAL_SECTION *mutex, DWORD wait)
90{ // SleepConditionVariableCS
91 EnterCriticalSection(&cond->broadcastMutex);
92 EnterCriticalSection(&cond->waiterCountMutex);
93 cond->waiterCount++;
94 LeaveCriticalSection(&cond->waiterCountMutex);
95 LeaveCriticalSection(&cond->broadcastMutex);
96
97 // unlock the external mutex
98 LeaveCriticalSection(mutex);
99 BOOL ret = WaitForSingleObject(cond->semaphore, wait);
100
101 EnterCriticalSection(&cond->waiterCountMutex);
102 cond->waiterCount--;
103 int last_waiter = !cond->waiterCount || !cond->bIsBroadcast;
104 LeaveCriticalSection(&cond->waiterCountMutex);
105
106 if (last_waiter)
107 SetEvent(cond->waitersDone);
108
109 // lock the external mutex
110 EnterCriticalSection(mutex);
111
112 // returns false on timeout or error
113 return ret;
114}
115
116/* Native CONDITION_VARIABLE instances are not freed, so this is a special case */
117void cond_destroy(ConditionVariable *cond)
118{
119 CloseHandle(cond->semaphore);
120 CloseHandle(cond->waitersDone);
121 DeleteCriticalSection(&cond->broadcastMutex);
122 DeleteCriticalSection(&cond->waiterCountMutex);
123}
124} // namespace x265
125
126#elif defined(_MSC_VER)
127
128namespace { int _avoid_linker_warnings = 0; }
129
130#endif // _WIN32_WINNT <= _WIN32_WINNT_WINXP