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 "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