1 #include <ossim/base/RWLock.h>
2 
RWLock()3 ossim::RWLock::RWLock() :
4         m_refCounter(0),
5         MIN_INT(std::numeric_limits<int>::min())
6 {
7 
8 }
9 
lockWrite()10 void ossim::RWLock::lockWrite()
11 {
12     int expected = 0;
13     if(!m_refCounter.compare_exchange_strong(expected, MIN_INT,
14                                              std::memory_order_acquire,
15                                              std::memory_order_relaxed)){
16         expected = 0;
17 
18         std::unique_lock<std::mutex> lk(m_waitMutex);
19         m_waitConditional.wait(lk, [this,&expected] {
20             if(!m_refCounter.compare_exchange_strong(expected, MIN_INT,
21                                                      std::memory_order_acquire,
22                                                      std::memory_order_relaxed)){
23                 expected = 0;
24                 return false;
25             }
26             return true;
27         });
28         lk.unlock();
29     }
30 }
31 
tryLockWrite()32 bool ossim::RWLock::tryLockWrite()
33 {
34     int expected = 0;
35     return m_refCounter.compare_exchange_strong(expected, MIN_INT,
36                                                 std::memory_order_acquire,
37                                                 std::memory_order_relaxed);
38 }
39 
unlockWrite()40 void ossim::RWLock::unlockWrite()
41 {
42     m_refCounter.store(0, std::memory_order_release);
43     m_waitConditional.notify_all();
44 }
45 
lockRead()46 void ossim::RWLock::lockRead()
47 {
48     if(m_refCounter.fetch_add(1, std::memory_order_acquire) < 0){
49         m_refCounter.fetch_sub(1, std::memory_order_release);
50 
51         std::unique_lock<std::mutex> lk(m_waitMutex);
52         m_waitConditional.wait(lk, [this]{
53             return m_refCounter.fetch_add(1, std::memory_order_acquire) >= 0;
54         });
55         lk.unlock();
56     }
57 }
58 
tryLockRead()59 bool ossim::RWLock::tryLockRead()
60 {
61     return m_refCounter.fetch_add(1, std::memory_order_acquire) >= 0;
62 }
63 
unlockRead()64 void ossim::RWLock::unlockRead()
65 {
66     m_refCounter.fetch_sub(1, std::memory_order_release);
67     m_waitConditional.notify_one();
68 }
69