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