16e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org/* 26e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 36e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * 46e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * Use of this source code is governed by a BSD-style license 56e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 66e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 76e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * in the file PATENTS. All contributing project authors may 86e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 96e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org */ 106e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 116e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 126e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org#include "webrtc/system_wrappers/source/condition_variable_native_win.h" 136e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org#include "webrtc/system_wrappers/source/critical_section_win.h" 146e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 156e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgnamespace webrtc { 166e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 176e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgstatic HMODULE library = NULL; 18c6f71c55ec3aa886689c78bb0f84d07473aca137wu@webrtc.orgstatic bool win_support_condition_variables_primitive = false; 196e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 206e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgPInitializeConditionVariable PInitializeConditionVariable_; 216e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgPSleepConditionVariableCS PSleepConditionVariableCS_; 226e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgPWakeConditionVariable PWakeConditionVariable_; 236e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgPWakeAllConditionVariable PWakeAllConditionVariable_; 246e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 256e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgtypedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE); 266e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgtypedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE, 276e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PCRITICAL_SECTION, DWORD); 286e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgtypedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE); 296e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgtypedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE); 306e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 316e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgConditionVariableNativeWin::ConditionVariableNativeWin() { 326e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 336e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 346e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgConditionVariableNativeWin::~ConditionVariableNativeWin() { 356e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 366e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 376e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgConditionVariableWrapper* ConditionVariableNativeWin::Create() { 386e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org ConditionVariableNativeWin* ret_val = new ConditionVariableNativeWin(); 396e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org if (!ret_val->Init()) { 406e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org delete ret_val; 416e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org return NULL; 426e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org } 436e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org return ret_val; 446e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 456e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 466e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgbool ConditionVariableNativeWin::Init() { 476e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org if (!library) { 486e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org // Native implementation is supported on Vista+. 496e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org library = LoadLibrary(TEXT("Kernel32.dll")); 506e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org // TODO(henrike): this code results in an attempt to load the above dll 516e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org // every time the previous attempt failed. Only try to load once. 526e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org if (library) { 536e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org // TODO(henrike): not thread safe as reading and writing to library is not 546e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org // serialized. Fix. 556e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll"); 566e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 576e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PInitializeConditionVariable_ = 586e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org (PInitializeConditionVariable) GetProcAddress( 596e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org library, "InitializeConditionVariable"); 606e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PSleepConditionVariableCS_ = (PSleepConditionVariableCS) GetProcAddress( 616e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org library, "SleepConditionVariableCS"); 626e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PWakeConditionVariable_ = (PWakeConditionVariable) GetProcAddress( 636e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org library, "WakeConditionVariable"); 646e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PWakeAllConditionVariable_ = (PWakeAllConditionVariable) GetProcAddress( 656e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org library, "WakeAllConditionVariable"); 666e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 676e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org if (PInitializeConditionVariable_ && PSleepConditionVariableCS_ 686e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org && PWakeConditionVariable_ && PWakeAllConditionVariable_) { 696e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org WEBRTC_TRACE( 706e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org kTraceStateInfo, kTraceUtility, -1, 716e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org "Loaded native condition variables"); 7214e22dde27f94d3275cfff53abe0556516e04061wu@webrtc.org win_support_condition_variables_primitive = true; 736e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org } 746e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org } 756e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org } 766e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org if (!win_support_condition_variables_primitive) { 776e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org return false; 786e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org } 796e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PInitializeConditionVariable_(&condition_variable_); 806e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org return true; 816e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 826e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 836e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgvoid ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect) { 846e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org SleepCS(crit_sect, INFINITE); 856e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 866e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 876e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgbool ConditionVariableNativeWin::SleepCS(CriticalSectionWrapper& crit_sect, 886e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org unsigned long max_time_in_ms) { 896e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org CriticalSectionWindows* cs = 906e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org static_cast<CriticalSectionWindows*>(&crit_sect); 916e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org BOOL ret_val = PSleepConditionVariableCS_(&condition_variable_, 926e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org &(cs->crit), max_time_in_ms); 936e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org return ret_val != 0; 946e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 956e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 966e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgvoid ConditionVariableNativeWin::Wake() { 976e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PWakeConditionVariable_(&condition_variable_); 986e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 996e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 1006e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.orgvoid ConditionVariableNativeWin::WakeAll() { 1016e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org PWakeAllConditionVariable_(&condition_variable_); 1026e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} 1036e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org 1046e34ceb97c11f4d390742a8364e77a65b8a01200henrike@webrtc.org} // namespace webrtc 105