Skip to content

Commit e23023d

Browse files
bnoordhuiscodebytere
authored andcommitted
src: add ExclusiveAccess class
Similar to Rust's `std::sync::Mutex` in that it requires one to unwrap the object before accessing it, acquiring the mutex in the process. PR-URL: #31717 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: David Carlier <devnexen@gmail.com>
1 parent cd99dc7 commit e23023d

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/node_mutex.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include "util.h"
77
#include "uv.h"
88

9+
#include <memory> // std::shared_ptr<T>
10+
#include <utility> // std::forward<T>
11+
912
namespace node {
1013

1114
template <typename Traits> class ConditionVariableBase;
@@ -15,6 +18,51 @@ struct LibuvMutexTraits;
1518
using ConditionVariable = ConditionVariableBase<LibuvMutexTraits>;
1619
using Mutex = MutexBase<LibuvMutexTraits>;
1720

21+
template <typename T, typename MutexT = Mutex>
22+
class ExclusiveAccess {
23+
public:
24+
ExclusiveAccess() = default;
25+
26+
template <typename... Args>
27+
explicit ExclusiveAccess(Args&&... args)
28+
: item_(std::forward<Args>(args)...) {}
29+
30+
ExclusiveAccess(const ExclusiveAccess&) = delete;
31+
ExclusiveAccess& operator=(const ExclusiveAccess&) = delete;
32+
33+
class Scoped {
34+
public:
35+
// ExclusiveAccess will commonly be used in conjuction with std::shared_ptr
36+
// and without this constructor it's too easy to forget to keep a reference
37+
// around to the shared_ptr while operating on the ExclusiveAccess object.
38+
explicit Scoped(const std::shared_ptr<ExclusiveAccess>& shared)
39+
: shared_(shared)
40+
, scoped_lock_(shared->mutex_)
41+
, pointer_(&shared->item_) {}
42+
43+
explicit Scoped(ExclusiveAccess* exclusive_access)
44+
: shared_()
45+
, scoped_lock_(exclusive_access->mutex_)
46+
, pointer_(&exclusive_access->item_) {}
47+
48+
T& operator*() const { return *pointer_; }
49+
T* operator->() const { return pointer_; }
50+
51+
Scoped(const Scoped&) = delete;
52+
Scoped& operator=(const Scoped&) = delete;
53+
54+
private:
55+
std::shared_ptr<ExclusiveAccess> shared_;
56+
typename MutexT::ScopedLock scoped_lock_;
57+
T* const pointer_;
58+
};
59+
60+
private:
61+
friend class ScopedLock;
62+
MutexT mutex_;
63+
T item_;
64+
};
65+
1866
template <typename Traits>
1967
class MutexBase {
2068
public:

0 commit comments

Comments
 (0)