1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *
4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Use of this source code is governed by a BSD-style license
5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  that can be found in the LICENSE file in the root of the source
6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  tree. An additional intellectual property rights grant can be found
7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  in the file PATENTS.  All contributing project authors may
8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  be found in the AUTHORS file in the root of the source tree.
9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "rw_lock_generic.h"
12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "condition_variable_wrapper.h"
14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "critical_section_wrapper.h"
15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace webrtc {
17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRWLockWrapperGeneric::RWLockWrapperGeneric()
18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    : _readersActive(0),
19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _writerActive(false),
20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _readersWaiting(0),
21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _writersWaiting(0)
22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr  = CriticalSectionWrapper::CreateCriticalSection();
24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _readCondPtr  = ConditionVariableWrapper::CreateConditionVariable();
25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable();
26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRWLockWrapperGeneric::~RWLockWrapperGeneric()
29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    delete _writeCondPtr;
31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    delete _readCondPtr;
32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    delete _critSectPtr;
33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint RWLockWrapperGeneric::Init()
36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return 0;
38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid RWLockWrapperGeneric::AcquireLockExclusive()
41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Enter();
43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_writerActive || _readersActive > 0)
45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        ++_writersWaiting;
47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        while (_writerActive || _readersActive > 0)
49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            _writeCondPtr->SleepCS(*_critSectPtr);
51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        --_writersWaiting;
54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _writerActive = true;
56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Leave();
57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid RWLockWrapperGeneric::ReleaseLockExclusive()
60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Enter();
62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _writerActive = false;
64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_writersWaiting > 0)
66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _writeCondPtr->Wake();
68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }else if (_readersWaiting > 0)
70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _readCondPtr->WakeAll();
72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Leave();
74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid RWLockWrapperGeneric::AcquireLockShared()
77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Enter();
79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_writerActive || _writersWaiting > 0)
81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        ++_readersWaiting;
83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        while (_writerActive || _writersWaiting > 0)
85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            _readCondPtr->SleepCS(*_critSectPtr);
87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        --_readersWaiting;
89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ++_readersActive;
91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Leave();
92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid RWLockWrapperGeneric::ReleaseLockShared()
95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Enter();
97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    --_readersActive;
99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_readersActive == 0 && _writersWaiting > 0)
101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _writeCondPtr->Wake();
103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _critSectPtr->Leave();
105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc
107