GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_mutex.h Lines: 60 60 100.0 %
Date: 2019-09-23 22:30:09 Branches: 2 4 50.0 %

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