GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/node_mutex.h Lines: 23 27 85.2 %
Date: 2016-07-26 Branches: 2 4 50.0 %

Line Exec Source
1
#ifndef SRC_NODE_MUTEX_H_
2
#define SRC_NODE_MUTEX_H_
3
4
#include "util.h"
5
#include "uv.h"
6
7
namespace node {
8
9
template <typename Traits> class ConditionVariableBase;
10
template <typename Traits> class MutexBase;
11
struct LibuvMutexTraits;
12
13
using ConditionVariable = ConditionVariableBase<LibuvMutexTraits>;
14
using Mutex = MutexBase<LibuvMutexTraits>;
15
16
template <typename Traits>
17
class MutexBase {
18
 public:
19
  inline MutexBase();
20
  inline ~MutexBase();
21
  inline void Lock();
22
  inline void Unlock();
23
24
  class ScopedLock;
25
  class ScopedUnlock;
26
27
  class ScopedLock {
28
   public:
29
    inline explicit ScopedLock(const MutexBase& mutex);
30
    inline explicit ScopedLock(const ScopedUnlock& scoped_unlock);
31
    inline ~ScopedLock();
32
33
   private:
34
    template <typename> friend class ConditionVariableBase;
35
    friend class ScopedUnlock;
36
    const MutexBase& mutex_;
37
    DISALLOW_COPY_AND_ASSIGN(ScopedLock);
38
  };
39
40
  class ScopedUnlock {
41
   public:
42
    inline explicit ScopedUnlock(const ScopedLock& scoped_lock);
43
    inline ~ScopedUnlock();
44
45
   private:
46
    friend class ScopedLock;
47
    const MutexBase& mutex_;
48
    DISALLOW_COPY_AND_ASSIGN(ScopedUnlock);
49
  };
50
51
 private:
52
  template <typename> friend class ConditionVariableBase;
53
  mutable typename Traits::MutexT mutex_;
54
  DISALLOW_COPY_AND_ASSIGN(MutexBase);
55
};
56
57
template <typename Traits>
58
class ConditionVariableBase {
59
 public:
60
  using ScopedLock = typename MutexBase<Traits>::ScopedLock;
61
62
  inline ConditionVariableBase();
63
  inline ~ConditionVariableBase();
64
  inline void Broadcast(const ScopedLock&);
65
  inline void Signal(const ScopedLock&);
66
  inline void Wait(const ScopedLock& scoped_lock);
67
68
 private:
69
  typename Traits::CondT cond_;
70
  DISALLOW_COPY_AND_ASSIGN(ConditionVariableBase);
71
};
72
73
struct LibuvMutexTraits {
74
  using CondT = uv_cond_t;
75
  using MutexT = uv_mutex_t;
76
77
  static inline int cond_init(CondT* cond) {
78
1561
    return uv_cond_init(cond);
79
  }
80
81
  static inline int mutex_init(MutexT* mutex) {
82
13711
    return uv_mutex_init(mutex);
83
  }
84
85
  static inline void cond_broadcast(CondT* cond) {
86
    uv_cond_broadcast(cond);
87
  }
88
89
  static inline void cond_destroy(CondT* cond) {
90
1366
    uv_cond_destroy(cond);
91
  }
92
93
  static inline void cond_signal(CondT* cond) {
94
    uv_cond_signal(cond);
95
  }
96
97
  static inline void cond_wait(CondT* cond, MutexT* mutex) {
98
    uv_cond_wait(cond, mutex);
99
  }
100
101
  static inline void mutex_destroy(MutexT* mutex) {
102
5664
    uv_mutex_destroy(mutex);
103
  }
104
105
  static inline void mutex_lock(MutexT* mutex) {
106
524804
    uv_mutex_lock(mutex);
107
  }
108
109
  static inline void mutex_unlock(MutexT* mutex) {
110
524804
    uv_mutex_unlock(mutex);
111
  }
112
};
113
114
template <typename Traits>
115
1561
ConditionVariableBase<Traits>::ConditionVariableBase() {
116
3122
  CHECK_EQ(0, Traits::cond_init(&cond_));
117
1561
}
118
119
template <typename Traits>
120
ConditionVariableBase<Traits>::~ConditionVariableBase() {
121
2732
  Traits::cond_destroy(&cond_);
122
1366
}
123
124
template <typename Traits>
125
void ConditionVariableBase<Traits>::Broadcast(const ScopedLock&) {
126
  Traits::cond_broadcast(&cond_);
127
}
128
129
template <typename Traits>
130
void ConditionVariableBase<Traits>::Signal(const ScopedLock&) {
131
  Traits::cond_signal(&cond_);
132
}
133
134
template <typename Traits>
135
void ConditionVariableBase<Traits>::Wait(const ScopedLock& scoped_lock) {
136
  Traits::cond_wait(&cond_, &scoped_lock.mutex_.mutex_);
137
}
138
139
template <typename Traits>
140
13711
MutexBase<Traits>::MutexBase() {
141
27422
  CHECK_EQ(0, Traits::mutex_init(&mutex_));
142
13711
}
143
144
template <typename Traits>
145
1566
MutexBase<Traits>::~MutexBase() {
146
11328
  Traits::mutex_destroy(&mutex_);
147
5664
}
148
149
template <typename Traits>
150
void MutexBase<Traits>::Lock() {
151
1043744
  Traits::mutex_lock(&mutex_);
152
}
153
154
template <typename Traits>
155
void MutexBase<Traits>::Unlock() {
156
1043744
  Traits::mutex_unlock(&mutex_);
157
}
158
159
template <typename Traits>
160
MutexBase<Traits>::ScopedLock::ScopedLock(const MutexBase& mutex)
161
2932
    : mutex_(mutex) {
162
5864
  Traits::mutex_lock(&mutex_.mutex_);
163
}
164
165
template <typename Traits>
166
MutexBase<Traits>::ScopedLock::ScopedLock(const ScopedUnlock& scoped_unlock)
167
    : MutexBase(scoped_unlock.mutex_) {}
168
169
template <typename Traits>
170
MutexBase<Traits>::ScopedLock::~ScopedLock() {
171
5864
  Traits::mutex_unlock(&mutex_.mutex_);
172
2932
}
173
174
template <typename Traits>
175
MutexBase<Traits>::ScopedUnlock::ScopedUnlock(const ScopedLock& scoped_lock)
176
    : mutex_(scoped_lock.mutex_) {
177
  Traits::mutex_unlock(&mutex_.mutex_);
178
}
179
180
template <typename Traits>
181
MutexBase<Traits>::ScopedUnlock::~ScopedUnlock() {
182
  Traits::mutex_lock(&mutex_.mutex_);
183
}
184
185
}  // namespace node
186
187
#endif  // SRC_NODE_MUTEX_H_