TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Michael Vandeberg
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/corosio
8 : //
9 :
10 : #ifndef BOOST_COROSIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
11 : #define BOOST_COROSIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
12 :
13 : #include <mutex>
14 :
15 : namespace boost::corosio::detail {
16 :
17 : /* Mutex wrapper that becomes a no-op when disabled.
18 :
19 : When enabled (the default), lock/unlock delegate to an
20 : underlying std::mutex. When disabled, all operations are
21 : no-ops. The enabled flag is fixed after construction.
22 :
23 : scoped_lock wraps std::unique_lock<std::mutex> internally
24 : so that condvar wait paths (which require the real lock
25 : type) compile and work in multi-threaded mode.
26 : */
27 : class conditionally_enabled_mutex
28 : {
29 : std::mutex mutex_;
30 : bool enabled_;
31 :
32 : public:
33 HIT 19543 : explicit conditionally_enabled_mutex(bool enabled = true) noexcept
34 19543 : : enabled_(enabled)
35 : {
36 19543 : }
37 :
38 : conditionally_enabled_mutex(conditionally_enabled_mutex const&) = delete;
39 : conditionally_enabled_mutex&
40 : operator=(conditionally_enabled_mutex const&) = delete;
41 :
42 : bool enabled() const noexcept
43 : {
44 : return enabled_;
45 : }
46 :
47 12607 : void set_enabled(bool v) noexcept
48 : {
49 12607 : enabled_ = v;
50 12607 : }
51 :
52 : // Lockable interface — allows std::lock_guard<conditionally_enabled_mutex>
53 68609 : void lock()
54 : {
55 68609 : if (enabled_)
56 68609 : mutex_.lock();
57 68609 : }
58 68609 : void unlock()
59 : {
60 68609 : if (enabled_)
61 68609 : mutex_.unlock();
62 68609 : }
63 : bool try_lock()
64 : {
65 : return !enabled_ || mutex_.try_lock();
66 : }
67 :
68 : class scoped_lock
69 : {
70 : std::unique_lock<std::mutex> lock_;
71 : bool enabled_;
72 :
73 : public:
74 880127 : explicit scoped_lock(conditionally_enabled_mutex& m)
75 880127 : : lock_(m.mutex_, std::defer_lock)
76 880127 : , enabled_(m.enabled_)
77 : {
78 880127 : if (enabled_)
79 880107 : lock_.lock();
80 880127 : }
81 :
82 : scoped_lock(scoped_lock const&) = delete;
83 : scoped_lock& operator=(scoped_lock const&) = delete;
84 :
85 833904 : void lock()
86 : {
87 833904 : if (enabled_)
88 833896 : lock_.lock();
89 833904 : }
90 :
91 847285 : void unlock()
92 : {
93 847285 : if (enabled_)
94 847277 : lock_.unlock();
95 847285 : }
96 :
97 842954 : bool owns_lock() const noexcept
98 : {
99 842954 : return enabled_ && lock_.owns_lock();
100 : }
101 :
102 : // Access the underlying unique_lock for condvar wait().
103 : // Only called when locking is enabled.
104 57 : std::unique_lock<std::mutex>& underlying() noexcept
105 : {
106 57 : return lock_;
107 : }
108 : };
109 : };
110 :
111 : } // namespace boost::corosio::detail
112 :
113 : #endif // BOOST_COROSIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
|