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 "rw_lock_generic.h" 12 13 #include "condition_variable_wrapper.h" 14 #include "critical_section_wrapper.h" 15 16 namespace webrtc { 17 RWLockWrapperGeneric::RWLockWrapperGeneric() 18 : _readersActive(0), 19 _writerActive(false), 20 _readersWaiting(0), 21 _writersWaiting(0) 22 { 23 _critSectPtr = CriticalSectionWrapper::CreateCriticalSection(); 24 _readCondPtr = ConditionVariableWrapper::CreateConditionVariable(); 25 _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable(); 26 } 27 28 RWLockWrapperGeneric::~RWLockWrapperGeneric() 29 { 30 delete _writeCondPtr; 31 delete _readCondPtr; 32 delete _critSectPtr; 33 } 34 35 int RWLockWrapperGeneric::Init() 36 { 37 return 0; 38 } 39 40 void RWLockWrapperGeneric::AcquireLockExclusive() 41 { 42 _critSectPtr->Enter(); 43 44 if (_writerActive || _readersActive > 0) 45 { 46 ++_writersWaiting; 47 48 while (_writerActive || _readersActive > 0) 49 { 50 _writeCondPtr->SleepCS(*_critSectPtr); 51 } 52 53 --_writersWaiting; 54 } 55 _writerActive = true; 56 _critSectPtr->Leave(); 57 } 58 59 void RWLockWrapperGeneric::ReleaseLockExclusive() 60 { 61 _critSectPtr->Enter(); 62 63 _writerActive = false; 64 65 if (_writersWaiting > 0) 66 { 67 _writeCondPtr->Wake(); 68 69 }else if (_readersWaiting > 0) 70 { 71 _readCondPtr->WakeAll(); 72 } 73 _critSectPtr->Leave(); 74 } 75 76 void RWLockWrapperGeneric::AcquireLockShared() 77 { 78 _critSectPtr->Enter(); 79 80 if (_writerActive || _writersWaiting > 0) 81 { 82 ++_readersWaiting; 83 84 while (_writerActive || _writersWaiting > 0) 85 { 86 _readCondPtr->SleepCS(*_critSectPtr); 87 } 88 --_readersWaiting; 89 } 90 ++_readersActive; 91 _critSectPtr->Leave(); 92 } 93 94 void RWLockWrapperGeneric::ReleaseLockShared() 95 { 96 _critSectPtr->Enter(); 97 98 --_readersActive; 99 100 if (_readersActive == 0 && _writersWaiting > 0) 101 { 102 _writeCondPtr->Wake(); 103 } 104 _critSectPtr->Leave(); 105 } 106 } // namespace webrtc 107