diff options
author | Anna Henningsen <anna@addaleax.net> | 2021-05-23 17:17:06 +0300 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2021-05-25 17:19:04 +0300 |
commit | 46eb417b6f304ed6e22f3366fda228116b020261 (patch) | |
tree | a49e3e64dcaa67e43f52d4ba560ade792baba724 /src/node_mutex.h | |
parent | f9447b71a6b458adbb265f8a5fd38ebf41bc97a4 (diff) |
worker: use rwlock for sibling group
Since it is much more common to send messages than to add or
remove ports from a sibling group, using a rwlock is appropriate here.
Refs: https://github.com/nodejs/node/issues/38780#issuecomment-846548949
PR-URL: https://github.com/nodejs/node/pull/38783
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src/node_mutex.h')
-rw-r--r-- | src/node_mutex.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/node_mutex.h b/src/node_mutex.h index 40c44c6d4fa..69e64ba27c3 100644 --- a/src/node_mutex.h +++ b/src/node_mutex.h @@ -14,9 +14,11 @@ namespace node { template <typename Traits> class ConditionVariableBase; template <typename Traits> class MutexBase; struct LibuvMutexTraits; +struct LibuvRwlockTraits; using ConditionVariable = ConditionVariableBase<LibuvMutexTraits>; using Mutex = MutexBase<LibuvMutexTraits>; +using RwLock = MutexBase<LibuvRwlockTraits>; template <typename T, typename MutexT = Mutex> class ExclusiveAccess { @@ -70,6 +72,8 @@ class MutexBase { inline ~MutexBase(); inline void Lock(); inline void Unlock(); + inline void RdLock(); + inline void RdUnlock(); MutexBase(const MutexBase&) = delete; MutexBase& operator=(const MutexBase&) = delete; @@ -92,6 +96,21 @@ class MutexBase { const MutexBase& mutex_; }; + class ScopedReadLock { + public: + inline explicit ScopedReadLock(const MutexBase& mutex); + inline ~ScopedReadLock(); + + ScopedReadLock(const ScopedReadLock&) = delete; + ScopedReadLock& operator=(const ScopedReadLock&) = delete; + + private: + template <typename> friend class ConditionVariableBase; + const MutexBase& mutex_; + }; + + using ScopedWriteLock = ScopedLock; + class ScopedUnlock { public: inline explicit ScopedUnlock(const ScopedLock& scoped_lock); @@ -167,6 +186,42 @@ struct LibuvMutexTraits { static inline void mutex_unlock(MutexT* mutex) { uv_mutex_unlock(mutex); } + + static inline void mutex_rdlock(MutexT* mutex) { + uv_mutex_lock(mutex); + } + + static inline void mutex_rdunlock(MutexT* mutex) { + uv_mutex_unlock(mutex); + } +}; + +struct LibuvRwlockTraits { + using MutexT = uv_rwlock_t; + + static inline int mutex_init(MutexT* mutex) { + return uv_rwlock_init(mutex); + } + + static inline void mutex_destroy(MutexT* mutex) { + uv_rwlock_destroy(mutex); + } + + static inline void mutex_lock(MutexT* mutex) { + uv_rwlock_wrlock(mutex); + } + + static inline void mutex_unlock(MutexT* mutex) { + uv_rwlock_wrunlock(mutex); + } + + static inline void mutex_rdlock(MutexT* mutex) { + uv_rwlock_rdlock(mutex); + } + + static inline void mutex_rdunlock(MutexT* mutex) { + uv_rwlock_rdunlock(mutex); + } }; template <typename Traits> @@ -215,6 +270,16 @@ void MutexBase<Traits>::Unlock() { } template <typename Traits> +void MutexBase<Traits>::RdLock() { + Traits::mutex_rdlock(&mutex_); +} + +template <typename Traits> +void MutexBase<Traits>::RdUnlock() { + Traits::mutex_rdunlock(&mutex_); +} + +template <typename Traits> MutexBase<Traits>::ScopedLock::ScopedLock(const MutexBase& mutex) : mutex_(mutex) { Traits::mutex_lock(&mutex_.mutex_); @@ -230,6 +295,17 @@ MutexBase<Traits>::ScopedLock::~ScopedLock() { } template <typename Traits> +MutexBase<Traits>::ScopedReadLock::ScopedReadLock(const MutexBase& mutex) + : mutex_(mutex) { + Traits::mutex_rdlock(&mutex_.mutex_); +} + +template <typename Traits> +MutexBase<Traits>::ScopedReadLock::~ScopedReadLock() { + Traits::mutex_rdunlock(&mutex_.mutex_); +} + +template <typename Traits> MutexBase<Traits>::ScopedUnlock::ScopedUnlock(const ScopedLock& scoped_lock) : mutex_(scoped_lock.mutex_) { Traits::mutex_unlock(&mutex_.mutex_); |