• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RWLockGeneric()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 
~RWLockGeneric()28 RWLockGeneric::~RWLockGeneric() {
29   delete write_condition_;
30   delete read_condition_;
31   delete critical_section_;
32 }
33 
AcquireLockExclusive()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 
ReleaseLockExclusive()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 
AcquireLockShared()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 
ReleaseLockShared()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