GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/node_mutex.h Lines: 59 59 100.0 %
Date: 2017-12-18 Branches: 2 4 50.0 %

Line Branch 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
20216
  static inline int cond_init(CondT* cond) {
78
20216
    return uv_cond_init(cond);
79
  }
80
81
40924
  static inline int mutex_init(MutexT* mutex) {
82
40924
    return uv_mutex_init(mutex);
83
  }
84
85
70563
  static inline void cond_broadcast(CondT* cond) {
86
70563
    uv_cond_broadcast(cond);
87
70563
  }
88
89
17853
  static inline void cond_destroy(CondT* cond) {
90
17853
    uv_cond_destroy(cond);
91
17853
  }
92
93
97852
  static inline void cond_signal(CondT* cond) {
94
97852
    uv_cond_signal(cond);
95
97852
  }
96
97
109427
  static inline void cond_wait(CondT* cond, MutexT* mutex) {
98
109427
    uv_cond_wait(cond, mutex);
99
108047
  }
100
101
22163
  static inline void mutex_destroy(MutexT* mutex) {
102
22163
    uv_mutex_destroy(mutex);
103
22163
  }
104
105
1276121
  static inline void mutex_lock(MutexT* mutex) {
106
1276121
    uv_mutex_lock(mutex);
107
1276987
  }
108
109
1275606
  static inline void mutex_unlock(MutexT* mutex) {
110
1275606
    uv_mutex_unlock(mutex);
111
1275352
  }
112
};
113
114
template <typename Traits>
115
20216
ConditionVariableBase<Traits>::ConditionVariableBase() {
116
20216
  CHECK_EQ(0, Traits::cond_init(&cond_));
117
20216
}
118
119
template <typename Traits>
120
17853
ConditionVariableBase<Traits>::~ConditionVariableBase() {
121
17853
  Traits::cond_destroy(&cond_);
122
17853
}
123
124
template <typename Traits>
125
70563
void ConditionVariableBase<Traits>::Broadcast(const ScopedLock&) {
126
70563
  Traits::cond_broadcast(&cond_);
127
70563
}
128
129
template <typename Traits>
130
97852
void ConditionVariableBase<Traits>::Signal(const ScopedLock&) {
131
97852
  Traits::cond_signal(&cond_);
132
97852
}
133
134
template <typename Traits>
135
109427
void ConditionVariableBase<Traits>::Wait(const ScopedLock& scoped_lock) {
136
109427
  Traits::cond_wait(&cond_, &scoped_lock.mutex_.mutex_);
137
108047
}
138
139
template <typename Traits>
140
40924
MutexBase<Traits>::MutexBase() {
141
40924
  CHECK_EQ(0, Traits::mutex_init(&mutex_));
142
40924
}
143
144
template <typename Traits>
145
22163
MutexBase<Traits>::~MutexBase() {
146
22163
  Traits::mutex_destroy(&mutex_);
147
22163
}
148
149
template <typename Traits>
150
897987
void MutexBase<Traits>::Lock() {
151
897987
  Traits::mutex_lock(&mutex_);
152
897987
}
153
154
template <typename Traits>
155
897987
void MutexBase<Traits>::Unlock() {
156
897987
  Traits::mutex_unlock(&mutex_);
157
897987
}
158
159
template <typename Traits>
160
370318
MutexBase<Traits>::ScopedLock::ScopedLock(const MutexBase& mutex)
161
370318
    : mutex_(mutex) {
162
370318
  Traits::mutex_lock(&mutex_.mutex_);
163
371172
}
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
369792
MutexBase<Traits>::ScopedLock::~ScopedLock() {
171
369792
  Traits::mutex_unlock(&mutex_.mutex_);
172
369547
}
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_