Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 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/source/rw_lock_generic.h"
     12 
     13 #include "webrtc/system_wrappers/include/condition_variable_wrapper.h"
     14 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     15 
     16 namespace webrtc {
     17 
     18 RWLockGeneric::RWLockGeneric()
     19     : readers_active_(0),
     20       writer_active_(false),
     21       readers_waiting_(0),
     22       writers_waiting_(0) {
     23   critical_section_ = CriticalSectionWrapper::CreateCriticalSection();
     24   read_condition_ = ConditionVariableWrapper::CreateConditionVariable();
     25   write_condition_ = ConditionVariableWrapper::CreateConditionVariable();
     26 }
     27 
     28 RWLockGeneric::~RWLockGeneric() {
     29   delete write_condition_;
     30   delete read_condition_;
     31   delete critical_section_;
     32 }
     33 
     34 void RWLockGeneric::AcquireLockExclusive() {
     35   CriticalSectionScoped cs(critical_section_);
     36   if (writer_active_ || readers_active_ > 0) {
     37     ++writers_waiting_;
     38     while (writer_active_ || readers_active_ > 0) {
     39       write_condition_->SleepCS(*critical_section_);
     40     }
     41     --writers_waiting_;
     42   }
     43   writer_active_ = true;
     44 }
     45 
     46 void RWLockGeneric::ReleaseLockExclusive() {
     47   CriticalSectionScoped cs(critical_section_);
     48   writer_active_ = false;
     49   if (writers_waiting_ > 0) {
     50     write_condition_->Wake();
     51   } else if (readers_waiting_ > 0) {
     52     read_condition_->WakeAll();
     53   }
     54 }
     55 
     56 void RWLockGeneric::AcquireLockShared() {
     57   CriticalSectionScoped cs(critical_section_);
     58   if (writer_active_ || writers_waiting_ > 0) {
     59     ++readers_waiting_;
     60 
     61     while (writer_active_ || writers_waiting_ > 0) {
     62       read_condition_->SleepCS(*critical_section_);
     63     }
     64     --readers_waiting_;
     65   }
     66   ++readers_active_;
     67 }
     68 
     69 void RWLockGeneric::ReleaseLockShared() {
     70   CriticalSectionScoped cs(critical_section_);
     71   --readers_active_;
     72   if (readers_active_ == 0 && writers_waiting_ > 0) {
     73     write_condition_->Wake();
     74   }
     75 }
     76 
     77 }  // namespace webrtc
     78