@@ -14,9 +14,11 @@ namespace node {
1414template <typename Traits> class ConditionVariableBase ;
1515template <typename Traits> class MutexBase ;
1616struct LibuvMutexTraits ;
17+ struct LibuvRwlockTraits ;
1718
1819using ConditionVariable = ConditionVariableBase<LibuvMutexTraits>;
1920using Mutex = MutexBase<LibuvMutexTraits>;
21+ using RwLock = MutexBase<LibuvRwlockTraits>;
2022
2123template <typename T, typename MutexT = Mutex>
2224class ExclusiveAccess {
@@ -70,6 +72,8 @@ class MutexBase {
7072 inline ~MutexBase ();
7173 inline void Lock ();
7274 inline void Unlock ();
75+ inline void RdLock ();
76+ inline void RdUnlock ();
7377
7478 MutexBase (const MutexBase&) = delete ;
7579 MutexBase& operator =(const MutexBase&) = delete ;
@@ -92,6 +96,21 @@ class MutexBase {
9296 const MutexBase& mutex_;
9397 };
9498
99+ class ScopedReadLock {
100+ public:
101+ inline explicit ScopedReadLock (const MutexBase& mutex);
102+ inline ~ScopedReadLock ();
103+
104+ ScopedReadLock (const ScopedReadLock&) = delete ;
105+ ScopedReadLock& operator =(const ScopedReadLock&) = delete ;
106+
107+ private:
108+ template <typename > friend class ConditionVariableBase ;
109+ const MutexBase& mutex_;
110+ };
111+
112+ using ScopedWriteLock = ScopedLock;
113+
95114 class ScopedUnlock {
96115 public:
97116 inline explicit ScopedUnlock (const ScopedLock& scoped_lock);
@@ -167,6 +186,42 @@ struct LibuvMutexTraits {
167186 static inline void mutex_unlock (MutexT* mutex) {
168187 uv_mutex_unlock (mutex);
169188 }
189+
190+ static inline void mutex_rdlock (MutexT* mutex) {
191+ uv_mutex_lock (mutex);
192+ }
193+
194+ static inline void mutex_rdunlock (MutexT* mutex) {
195+ uv_mutex_unlock (mutex);
196+ }
197+ };
198+
199+ struct LibuvRwlockTraits {
200+ using MutexT = uv_rwlock_t ;
201+
202+ static inline int mutex_init (MutexT* mutex) {
203+ return uv_rwlock_init (mutex);
204+ }
205+
206+ static inline void mutex_destroy (MutexT* mutex) {
207+ uv_rwlock_destroy (mutex);
208+ }
209+
210+ static inline void mutex_lock (MutexT* mutex) {
211+ uv_rwlock_wrlock (mutex);
212+ }
213+
214+ static inline void mutex_unlock (MutexT* mutex) {
215+ uv_rwlock_wrunlock (mutex);
216+ }
217+
218+ static inline void mutex_rdlock (MutexT* mutex) {
219+ uv_rwlock_rdlock (mutex);
220+ }
221+
222+ static inline void mutex_rdunlock (MutexT* mutex) {
223+ uv_rwlock_rdunlock (mutex);
224+ }
170225};
171226
172227template <typename Traits>
@@ -214,6 +269,16 @@ void MutexBase<Traits>::Unlock() {
214269 Traits::mutex_unlock (&mutex_);
215270}
216271
272+ template <typename Traits>
273+ void MutexBase<Traits>::RdLock() {
274+ Traits::mutex_rdlock (&mutex_);
275+ }
276+
277+ template <typename Traits>
278+ void MutexBase<Traits>::RdUnlock() {
279+ Traits::mutex_rdunlock (&mutex_);
280+ }
281+
217282template <typename Traits>
218283MutexBase<Traits>::ScopedLock::ScopedLock(const MutexBase& mutex)
219284 : mutex_(mutex) {
@@ -229,6 +294,17 @@ MutexBase<Traits>::ScopedLock::~ScopedLock() {
229294 Traits::mutex_unlock (&mutex_.mutex_ );
230295}
231296
297+ template <typename Traits>
298+ MutexBase<Traits>::ScopedReadLock::ScopedReadLock(const MutexBase& mutex)
299+ : mutex_(mutex) {
300+ Traits::mutex_rdlock (&mutex_.mutex_ );
301+ }
302+
303+ template <typename Traits>
304+ MutexBase<Traits>::ScopedReadLock::~ScopedReadLock () {
305+ Traits::mutex_rdunlock (&mutex_.mutex_ );
306+ }
307+
232308template <typename Traits>
233309MutexBase<Traits>::ScopedUnlock::ScopedUnlock(const ScopedLock& scoped_lock)
234310 : mutex_(scoped_lock.mutex_) {
0 commit comments