Home | History | Annotate | Download | only in source
      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