1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/system_wrappers/include/trace.h"
12 #include "webrtc/system_wrappers/source/condition_variable_native_win.h"
13 #include "webrtc/system_wrappers/source/critical_section_win.h"
14
15 namespace webrtc {
16
17 static HMODULE library = NULL;
18 static bool win_support_condition_variables_primitive = false;
19
20 PInitializeConditionVariable PInitializeConditionVariable_;
21 PSleepConditionVariableCS PSleepConditionVariableCS_;
22 PWakeConditionVariable PWakeConditionVariable_;
23 PWakeAllConditionVariable PWakeAllConditionVariable_;
24
25 typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
26 typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
27 PCRITICAL_SECTION, DWORD);
28 typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
29 typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
30
ConditionVariableNativeWin()31 ConditionVariableNativeWin::ConditionVariableNativeWin() {
32 }
33
~ConditionVariableNativeWin()34 ConditionVariableNativeWin::~ConditionVariableNativeWin() {
35 }
36
Create()37 ConditionVariableWrapper* ConditionVariableNativeWin::Create() {
38 ConditionVariableNativeWin* ret_val = new ConditionVariableNativeWin();
39 if (!ret_val->Init()) {
40 delete ret_val;
41 return NULL;
42 }
43 return ret_val;
44 }
45
Init()46 bool ConditionVariableNativeWin::Init() {
47 if (!library) {
48 // Native implementation is supported on Vista+.
49 library = LoadLibrary(TEXT("Kernel32.dll"));
50 // TODO(henrike): this code results in an attempt to load the above dll
51 // every time the previous attempt failed. Only try to load once.
52 if (library) {
53 // TODO(henrike): not thread safe as reading and writing to library is not
54 // serialized. Fix.
55 WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll");
56
57 PInitializeConditionVariable_ =
58 (PInitializeConditionVariable) GetProcAddress(
59 library, "InitializeConditionVariable");
60 PSleepConditionVariableCS_ = (PSleepConditionVariableCS) GetProcAddress(
61 library, "SleepConditionVariableCS");
62 PWakeConditionVariable_ = (PWakeConditionVariable) GetProcAddress(
63 library, "WakeConditionVariable");
64 PWakeAllConditionVariable_ = (PWakeAllConditionVariable) GetProcAddress(
65 library, "WakeAllConditionVariable");
66
67 if (PInitializeConditionVariable_ && PSleepConditionVariableCS_
68 && PWakeConditionVariable_ && PWakeAllConditionVariable_) {
69 WEBRTC_TRACE(
70 kTraceStateInfo, kTraceUtility, -1,
71 "Loaded native condition variables");
72 win_support_condition_variables_primitive = true;
73 }
74 }
75 }
76 if (!win_support_condition_variables_primitive) {
77 return false;
78 }
79 PInitializeConditionVariable_(&condition_variable_);
80 return true;
81 }
82
SleepCS(CriticalSectionWrapper & crit_sect)83 void ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect) {
84 SleepCS(crit_sect, INFINITE);
85 }
86
SleepCS(CriticalSectionWrapper & crit_sect,unsigned long max_time_in_ms)87 bool ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect,
88 unsigned long max_time_in_ms) {
89 CriticalSectionWindows* cs =
90 static_cast<CriticalSectionWindows*>(&crit_sect);
91 BOOL ret_val = PSleepConditionVariableCS_(&condition_variable_,
92 &(cs->crit), max_time_in_ms);
93 return ret_val != 0;
94 }
95
Wake()96 void ConditionVariableNativeWin::Wake() {
97 PWakeConditionVariable_(&condition_variable_);
98 }
99
WakeAll()100 void ConditionVariableNativeWin::WakeAll() {
101 PWakeAllConditionVariable_(&condition_variable_);
102 }
103
104 } // namespace webrtc
105