blob: 22ddb6f8fd0412b7e879a9198a3307e04752b6db [file] [log] [blame]
/*
* 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