/* * 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