|  | /* | 
|  | *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include "webrtc/system_wrappers/interface/trace.h" | 
|  | #include "webrtc/system_wrappers/source/condition_variable_native_win.h" | 
|  | #include "webrtc/system_wrappers/source/critical_section_win.h" | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | static HMODULE library = NULL; | 
|  | static bool win_support_condition_variables_primitive = false; | 
|  |  | 
|  | PInitializeConditionVariable  PInitializeConditionVariable_; | 
|  | PSleepConditionVariableCS     PSleepConditionVariableCS_; | 
|  | PWakeConditionVariable        PWakeConditionVariable_; | 
|  | PWakeAllConditionVariable     PWakeAllConditionVariable_; | 
|  |  | 
|  | typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE); | 
|  | typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE, | 
|  | PCRITICAL_SECTION, DWORD); | 
|  | typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE); | 
|  | typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE); | 
|  |  | 
|  | ConditionVariableNativeWin::ConditionVariableNativeWin() { | 
|  | } | 
|  |  | 
|  | ConditionVariableNativeWin::~ConditionVariableNativeWin() { | 
|  | } | 
|  |  | 
|  | ConditionVariableWrapper* ConditionVariableNativeWin::Create() { | 
|  | ConditionVariableNativeWin* ret_val = new ConditionVariableNativeWin(); | 
|  | if (!ret_val->Init()) { | 
|  | delete ret_val; | 
|  | return NULL; | 
|  | } | 
|  | return ret_val; | 
|  | } | 
|  |  | 
|  | bool ConditionVariableNativeWin::Init() { | 
|  | if (!library) { | 
|  | // Native implementation is supported on Vista+. | 
|  | library = LoadLibrary(TEXT("Kernel32.dll")); | 
|  | // TODO(henrike): this code results in an attempt to load the above dll | 
|  | // every time the previous attempt failed. Only try to load once. | 
|  | if (library) { | 
|  | // TODO(henrike): not thread safe as reading and writing to library is not | 
|  | // serialized. Fix. | 
|  | WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll"); | 
|  |  | 
|  | PInitializeConditionVariable_ = | 
|  | (PInitializeConditionVariable) GetProcAddress( | 
|  | library, "InitializeConditionVariable"); | 
|  | PSleepConditionVariableCS_ = (PSleepConditionVariableCS) GetProcAddress( | 
|  | library, "SleepConditionVariableCS"); | 
|  | PWakeConditionVariable_ = (PWakeConditionVariable) GetProcAddress( | 
|  | library, "WakeConditionVariable"); | 
|  | PWakeAllConditionVariable_ = (PWakeAllConditionVariable) GetProcAddress( | 
|  | library, "WakeAllConditionVariable"); | 
|  |  | 
|  | if (PInitializeConditionVariable_ && PSleepConditionVariableCS_ | 
|  | && PWakeConditionVariable_ && PWakeAllConditionVariable_) { | 
|  | WEBRTC_TRACE( | 
|  | kTraceStateInfo, kTraceUtility, -1, | 
|  | "Loaded native condition variables"); | 
|  | win_support_condition_variables_primitive = true; | 
|  | } | 
|  | } | 
|  | } | 
|  | if (!win_support_condition_variables_primitive) { | 
|  | return false; | 
|  | } | 
|  | PInitializeConditionVariable_(&condition_variable_); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect) { | 
|  | SleepCS(crit_sect, INFINITE); | 
|  | } | 
|  |  | 
|  | bool ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect, | 
|  | unsigned long max_time_in_ms) { | 
|  | CriticalSectionWindows* cs = | 
|  | static_cast<CriticalSectionWindows*>(&crit_sect); | 
|  | BOOL ret_val = PSleepConditionVariableCS_(&condition_variable_, | 
|  | &(cs->crit), max_time_in_ms); | 
|  | return ret_val != 0; | 
|  | } | 
|  |  | 
|  | void ConditionVariableNativeWin::Wake() { | 
|  | PWakeConditionVariable_(&condition_variable_); | 
|  | } | 
|  |  | 
|  | void ConditionVariableNativeWin::WakeAll() { | 
|  | PWakeAllConditionVariable_(&condition_variable_); | 
|  | } | 
|  |  | 
|  | }  // namespace webrtc |