FreeRTOScpp
Lock.h
Go to the documentation of this file.
1 /**
2  * @file Lock.h
3  * @brief FreeRTOS Lock wrapper
4  *
5  * A Generic Locking interface for Lockable objects.
6  *
7  * @copyright (c) 2018-2024 Richard Damon
8  * @author Richard Damon <richard.damon@gmail.com>
9  * @parblock
10  * MIT License:
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy
13  * of this software and associated documentation files (the "Software"), to deal
14  * in the Software without restriction, including without limitation the rights
15  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  * copies of the Software, and to permit persons to whom the Software is
17  * furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28  * THE SOFTWARE.
29  *
30  * It is requested (but not required by license) that any bugs found or
31  * improvements made be shared, preferably to the author.
32  * @endparblock
33  *
34  * @ingroup FreeRTOSCpp
35  */
36 
37 #ifndef FREERTOSPP_LOCK_H_
38 #define FREERTOSPP_LOCK_H_
39 
40 #include "FreeRTOScpp.h"
41 
42 #if FREERTOSCPP_USE_NAMESPACE
43 namespace FreeRTOScpp {
44 #endif
45 
46 /**
47  * A Base class to provide block based locking capability.
48  *
49  * Any object that supports "Locking" should be derived from Lockable (like a Semaphore or Mutex)
50  *
51  * Such objects need to provide an interface consisting of
52  * + virtual bool take(TickType_t wait)
53  * + virtual bool give();
54  *
55  * @ingroup FreeRTOSCpp
56  */
57 
58 class Lockable {
59 public:
60  Lockable() {}
61  virtual ~Lockable() {}
62 
63  virtual bool take(TickType_t wait = portMAX_DELAY) = 0;
64 #if FREERTOSCPP_USE_CHRONO
65  bool take(Time_ms ms) { return take(ms2ticks(ms)); }
66 #endif
67  virtual bool give() = 0;
68 private:
69 #if __cplusplus < 201101L
70  Lockable(Lockable const&); ///< We are not copyable.
71  void operator =(Lockable const&); ///< We are not assignable.
72 #else
73  Lockable(Lockable const&) = delete; ///< We are not copyable.
74  void operator =(Lockable const&) = delete; ///< We are not assignable.
75 #endif // __cplusplus
76 };
77 
78 /**
79  * Class to hold a block based lock. (auto unlocks on in its destructor)
80  *
81  * Typical calling sequences:
82  *
83  * @code
84  * // Somewhere global
85  * Mutex mutex
86  * @endcode
87  * then, in a block
88  * @code
89  * {
90  * Lock lock(mutex); // Mutex is taken here
91  * ...
92  * } // and released here
93  * @endcode
94  * or
95  * @code
96  *
97  * {
98  * Lock lokc(mutex, false); // don't take it yet
99  * ...
100  * if (lock.lock(5)) { // but take it here, with a maximum timeout
101  * ...
102  * lock.unlock(); // and possible release it
103  * }
104  *
105  * } // will be released here if taken and not released
106  * @endcode
107  * or
108  * @code
109  * {
110  * Lock lock(mute, 5); // Try to take the semaphore with a timeout
111  * if (lock.locked()) {
112  * // Semaphore was locked, so we could use it
113  * } else {
114  * // Error handling because we couldn't take the semaphore.
115  * }
116  * } // Mutex will be released here if not otherwise release
117  * @endcode
118  *
119  * @ingroup FreeRTOSCpp
120  */
121 class Lock {
122 public:
123  Lock(Lockable& mylockable, bool mylocked = true, TickType_t wait = portMAX_DELAY);
124  /**
125  * Constructor with assumed locking by specifying lock time
126  * @param mylockable The Lockabe object to use
127  * @param wait The time it Ticks to wait to get the lock.
128  */
129  Lock(Lockable& mylockable, TickType_t wait) : Lock(mylockable, true, wait) {}
130 #if FREERTOSCPP_USE_CHRONO
131  Lock(Lockable& mylockable, Time_ms wait);
132 #endif
133  virtual ~Lock();
134 
135  bool lock(TickType_t wait = portMAX_DELAY);
136 #if FREERTOSCPP_USE_CHRONO
137  bool lock(Time_ms ms) { return lock(ms2ticks(ms)); }
138 #endif
139  void unlock();
140  /**
141  * Do we have the lock?
142  * @return True if we have the lock.
143  */
144  bool locked() const { return lockCnt > 0; }
145 private:
146  Lockable& lockable; ///< The Lockage object we are connected to
147  int lockCnt; ///< The number of locks we hold on lockable.
148 
149 #if __cplusplus < 201101L
150  Lock(Lock const&); ///< We are not copyable.
151  void operator =(Lock const&); ///< We are not assignable.
152 #else
153  Lock(Lock const&) = delete; ///< We are not copyable.
154  void operator =(Lock const&) = delete; ///< We are not assignable.
155 #endif // __cplusplus
156 };
157 
158 #if FREERTOSCPP_USE_NAMESPACE
159 } // namespace FreeRTOScpp
160 #endif
161 #endif /* FREERTOSPP_LOCK_H_ */
Lock(Lockable &mylockable, TickType_t wait)
Constructor with assumed locking by specifying lock time.
Definition: Lock.h:129
Class to hold a block based lock.
Definition: Lock.h:121
Lockable & lockable
The Lockage object we are connected to.
Definition: Lock.h:146
constexpr TickType_t ms2ticks(Time_ms ms)
Definition: FreeRTOScpp.h:81
std::chrono::milliseconds Time_ms
Definition: FreeRTOScpp.h:79
void operator=(Lockable const &)=delete
We are not assignable.
Definition: CallBack.h:63
virtual bool give()=0
FreeRTOS Wrapper.
bool take(Time_ms ms)
Definition: Lock.h:65
A Base class to provide block based locking capability.
Definition: Lock.h:58
virtual bool take(TickType_t wait=portMAX_DELAY)=0
Lockable()
Definition: Lock.h:60
int lockCnt
The number of locks we hold on lockable.
Definition: Lock.h:147
bool locked() const
Do we have the lock?
Definition: Lock.h:144
virtual ~Lockable()
Definition: Lock.h:61
bool lock(Time_ms ms)
Definition: Lock.h:137