include/boost/corosio/detail/conditionally_enabled_mutex.hpp

100.0% Lines (36 / 36) 92.9% Branches (13 / 14) 100.0% Functions (12 / 12)
conditionally_enabled_mutex.hpp
f(x) Functions (12)
Line Branch TLA Hits 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 37937x explicit conditionally_enabled_mutex(bool enabled = true) noexcept
34 18968x : enabled_(enabled)
35 18969x {
36 37937x }
37
38 conditionally_enabled_mutex(conditionally_enabled_mutex const&) = delete;
39 conditionally_enabled_mutex&
40 operator=(conditionally_enabled_mutex const&) = delete;
41
42 36404x bool enabled() const noexcept
43 {
44 36404x return enabled_;
45 }
46
47 4634x void set_enabled(bool v) noexcept
48 {
49 4634x enabled_ = v;
50 4634x }
51
52 // Lockable interface — allows std::lock_guard<conditionally_enabled_mutex>
53 449554x void lock()
54 {
55
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 449527 times.
449554x if (enabled_)
56 449527x mutex_.lock();
57 449554x }
58 449547x void unlock()
59 {
60
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 449527 times.
449547x if (enabled_)
61 449527x mutex_.unlock();
62 449547x }
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 1510152x explicit scoped_lock(conditionally_enabled_mutex& m)
75 755067x : lock_(m.mutex_, std::defer_lock)
76 755067x , enabled_(m.enabled_)
77 755085x {
78
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 754987 times.
755067x if (enabled_)
79
1/2
✓ Branch 0 taken 754987 times.
✗ Branch 1 not taken.
754987x lock_.lock();
80 1510152x }
81
82 scoped_lock(scoped_lock const&) = delete;
83 scoped_lock& operator=(scoped_lock const&) = delete;
84
85 1168734x void lock()
86 {
87
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1168743 times.
1168734x if (enabled_)
88 1168743x lock_.lock();
89 1168752x }
90
91 1219881x void unlock()
92 {
93
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1219898 times.
1219881x if (enabled_)
94 1219898x lock_.unlock();
95 1219915x }
96
97 1226578x bool owns_lock() const noexcept
98 {
99
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1226572 times.
1226578x return enabled_ && lock_.owns_lock();
100 }
101
102 // Access the underlying unique_lock for condvar wait().
103 // Only called when locking is enabled.
104 6412x std::unique_lock<std::mutex>& underlying() noexcept
105 {
106 6412x return lock_;
107 }
108 };
109 };
110
111 } // namespace boost::corosio::detail
112
113 #endif // BOOST_COROSIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
114