include/boost/corosio/detail/conditionally_enabled_mutex.hpp

100.0% Lines (28/28) 100.0% List of functions (11/11) 78.6% Branches (11/14)
conditionally_enabled_mutex.hpp
f(x) Functions (11)
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 54116x explicit conditionally_enabled_mutex(bool enabled = true) noexcept
34 27058x : enabled_(enabled)
35 27058x {
36 54116x }
37
38 conditionally_enabled_mutex(conditionally_enabled_mutex const&) = delete;
39 conditionally_enabled_mutex& operator=(conditionally_enabled_mutex const&) = delete;
40
41 bool enabled() const noexcept
42 {
43 return enabled_;
44 }
45
46 17546x void set_enabled(bool v) noexcept
47 {
48 17546x enabled_ = v;
49 17546x }
50
51 // Lockable interface — allows std::lock_guard<conditionally_enabled_mutex>
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 234569 times.
234569x void lock() { if (enabled_) mutex_.lock(); }
53
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 234569 times.
234569x void unlock() { if (enabled_) mutex_.unlock(); }
54 bool try_lock() { return !enabled_ || mutex_.try_lock(); }
55
56 class scoped_lock
57 {
58 std::unique_lock<std::mutex> lock_;
59 bool enabled_;
60
61 public:
62 7154508x explicit scoped_lock(conditionally_enabled_mutex& m)
63 3577254x : lock_(m.mutex_, std::defer_lock)
64 3577254x , enabled_(m.enabled_)
65 3577254x {
66
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3577233 times.
3577254x if (enabled_)
67
1/2
✓ Branch 0 taken 3577233 times.
✗ Branch 1 not taken.
3577233x lock_.lock();
68 7154508x }
69
70 scoped_lock(scoped_lock const&) = delete;
71 scoped_lock& operator=(scoped_lock const&) = delete;
72
73 3297975x void lock()
74 {
75
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3297967 times.
3297975x if (enabled_)
76 3297967x lock_.lock();
77 3297975x }
78
79 3307848x void unlock()
80 {
81
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3307836 times.
3307848x if (enabled_)
82 3307836x lock_.unlock();
83 3307848x }
84
85 3305038x bool owns_lock() const noexcept
86 {
87
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3305030 times.
3305038x return enabled_ && lock_.owns_lock();
88 }
89
90 // Access the underlying unique_lock for condvar wait().
91 // Only called when locking is enabled.
92 4x std::unique_lock<std::mutex>& underlying() noexcept
93 {
94 4x return lock_;
95 }
96 };
97 };
98
99 } // namespace boost::corosio::detail
100
101 #endif // BOOST_COROSIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
102