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 31 ConditionVariableNativeWin::ConditionVariableNativeWin() { 32 } 33 34 ConditionVariableNativeWin::~ConditionVariableNativeWin() { 35 } 36 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 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 83 void ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect) { 84 SleepCS(crit_sect, INFINITE); 85 } 86 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 96 void ConditionVariableNativeWin::Wake() { 97 PWakeConditionVariable_(&condition_variable_); 98 } 99 100 void ConditionVariableNativeWin::WakeAll() { 101 PWakeAllConditionVariable_(&condition_variable_); 102 } 103 104 } // namespace webrtc 105