1a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
2a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Use of this source code is governed by the ACE copyright license which
3a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  can be found in the LICENSE file in the third_party_mods/ace directory of
4a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  the source tree or at http://www1.cse.wustl.edu/~schmidt/ACE-copying.html.
5a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
6a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
7a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  This source code contain modifications to the original source code
8a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  which can be found here:
9a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (section 3.2).
10a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Modifications:
11a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  1) Dynamic detection of native support for condition variables.
12a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  2) Use of WebRTC defined types and classes. Renaming of some functions.
13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  3) Introduction of a second event for wake all functionality. This prevents
14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *     a thread from spinning on the same condition variable, preventing other
15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *     threads from waking up.
16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin// TODO (hellner): probably nicer to split up native and generic
19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin// implementation into two different files
20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "condition_variable_win.h"
22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "critical_section_win.h"
24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "trace.h"
25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinnamespace webrtc {
27a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool ConditionVariableWindows::_winSupportConditionVariablesPrimitive = false;
28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic HMODULE library = NULL;
29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
30a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinPInitializeConditionVariable  _PInitializeConditionVariable;
31a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinPSleepConditionVariableCS     _PSleepConditionVariableCS;
32a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinPWakeConditionVariable        _PWakeConditionVariable;
33a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinPWakeAllConditionVariable     _PWakeAllConditionVariable;
34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkintypedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkintypedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
37a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                 PCRITICAL_SECTION, DWORD);
38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkintypedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkintypedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
41a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinConditionVariableWindows::ConditionVariableWindows()
42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    : _eventID(WAKEALL_0)
43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (!library)
45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // Use native implementation if supported (i.e Vista+)
47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        library = LoadLibrary(TEXT("Kernel32.dll"));
48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (library)
49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        {
50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                         "Loaded Kernel.dll");
52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            _PInitializeConditionVariable =
54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                (PInitializeConditionVariable) GetProcAddress(
55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    library,
56a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    "InitializeConditionVariable");
57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            _PSleepConditionVariableCS =
58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                (PSleepConditionVariableCS)GetProcAddress(
59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    library,
60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    "SleepConditionVariableCS");
61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            _PWakeConditionVariable =
62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                (PWakeConditionVariable)GetProcAddress(
63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    library,
64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                     "WakeConditionVariable");
65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            _PWakeAllConditionVariable =
66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                (PWakeAllConditionVariable)GetProcAddress(
67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    library,
68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                    "WakeAllConditionVariable");
69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            if(_PInitializeConditionVariable &&
71a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin               _PSleepConditionVariableCS &&
72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin               _PWakeConditionVariable &&
73a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin               _PWakeAllConditionVariable)
74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            {
75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                             "Loaded native condition variables");
77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                _winSupportConditionVariablesPrimitive = true;
78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            }
79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (_winSupportConditionVariablesPrimitive)
83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _PInitializeConditionVariable(&_conditionVariable);
85a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKEALL_0] = NULL;
87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKEALL_1] = NULL;
88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKE] = NULL;
89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        memset(&_numWaiters[0],0,sizeof(_numWaiters));
92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        InitializeCriticalSection(&_numWaitersCritSect);
94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKEALL_0] = CreateEvent(NULL,  // no security attributes
96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         TRUE,  // manual-reset, sticky event
97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         FALSE, // initial state non-signaled
98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         NULL); // no name for event
99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKEALL_1] = CreateEvent(NULL,  // no security attributes
101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         TRUE,  // manual-reset, sticky event
102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         FALSE, // initial state non-signaled
103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         NULL); // no name for event
104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _events[WAKE] = CreateEvent(NULL,  // no security attributes
106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                    FALSE, // auto-reset, sticky event
107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                    FALSE, // initial state non-signaled
108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                    NULL); // no name for event
109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
112a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinConditionVariableWindows::~ConditionVariableWindows()
113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if(!_winSupportConditionVariablesPrimitive)
115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        CloseHandle(_events[WAKE]);
117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        CloseHandle(_events[WAKEALL_1]);
118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        CloseHandle(_events[WAKEALL_0]);
119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        DeleteCriticalSection(&_numWaitersCritSect);
121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect)
125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    SleepCS(critSect, INFINITE);
127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect,
130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                       unsigned long maxTimeInMS)
131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    CriticalSectionWindows* cs = reinterpret_cast<CriticalSectionWindows*>(
133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                     &critSect);
134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if(_winSupportConditionVariablesPrimitive)
136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        BOOL retVal = _PSleepConditionVariableCS(&_conditionVariable,
138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                 &(cs->crit),maxTimeInMS);
139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        return (retVal == 0) ? false : true;
140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }else
142a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        EnterCriticalSection(&_numWaitersCritSect);
144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // Get the eventID for the event that will be triggered by next
145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // WakeAll() call and start waiting for it.
146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const EventWakeUpType eventID = (WAKEALL_0 == _eventID) ?
147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                            WAKEALL_1 : WAKEALL_0;
148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        ++(_numWaiters[eventID]);
149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        LeaveCriticalSection(&_numWaitersCritSect);
150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        LeaveCriticalSection(&cs->crit);
152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        HANDLE events[2];
153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        events[0] = _events[WAKE];
154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        events[1] = _events[eventID];
155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events.
156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                    events,
157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                    FALSE, // Wait for either.
158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                    maxTimeInMS);
159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const bool retVal = (result != WAIT_TIMEOUT);
161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        EnterCriticalSection(&_numWaitersCritSect);
163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        --(_numWaiters[eventID]);
164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // Last waiter should only be true for WakeAll(). WakeAll() correspond
165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1)
166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const bool lastWaiter = (result == WAIT_OBJECT_0 + 1) &&
167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                (_numWaiters[eventID] == 0);
168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        LeaveCriticalSection(&_numWaitersCritSect);
169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (lastWaiter)
171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        {
172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            // Reset/unset the WakeAll() event since all threads have been
173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            // released.
174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            ResetEvent(_events[eventID]);
175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        EnterCriticalSection(&cs->crit);
178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        return retVal;
179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid
183a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinConditionVariableWindows::Wake()
184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if(_winSupportConditionVariablesPrimitive)
186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _PWakeConditionVariable(&_conditionVariable);
188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }else
189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        EnterCriticalSection(&_numWaitersCritSect);
191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const bool haveWaiters = (_numWaiters[WAKEALL_0] > 0) ||
192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                 (_numWaiters[WAKEALL_1] > 0);
193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        LeaveCriticalSection(&_numWaitersCritSect);
194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (haveWaiters)
196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        {
197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            SetEvent(_events[WAKE]);
198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid
203a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinConditionVariableWindows::WakeAll()
204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if(_winSupportConditionVariablesPrimitive)
206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _PWakeAllConditionVariable(&_conditionVariable);
208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }else
209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    {
210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        EnterCriticalSection(&_numWaitersCritSect);
211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // Update current WakeAll() event
212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        _eventID = (WAKEALL_0 == _eventID) ? WAKEALL_1 : WAKEALL_0;
213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        // Trigger current event
214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const EventWakeUpType eventID = _eventID;
215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        const bool haveWaiters = _numWaiters[eventID] > 0;
216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        LeaveCriticalSection(&_numWaitersCritSect);
217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (haveWaiters)
219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        {
220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            SetEvent(_events[eventID]);
221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} // namespace webrtc
225