EtcPal  HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
View other versions:
rwlock.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 ETC Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************
16  * This file is a part of EtcPal. For more information, go to:
17  * https://github.com/ETCLabs/EtcPal
18  ******************************************************************************/
19 
22 
23 #ifndef ETCPAL_CPP_RWLOCK_H_
24 #define ETCPAL_CPP_RWLOCK_H_
25 
26 #include <stdexcept>
27 #include "etcpal/cpp/common.h"
28 #include "etcpal/rwlock.h"
29 
30 namespace etcpal
31 {
44 
111 class RwLock
112 {
113 public:
114  RwLock();
115  ~RwLock();
116 
117  RwLock(const RwLock& other) = delete;
118  RwLock& operator=(const RwLock& other) = delete;
119  RwLock(RwLock&& other) = delete;
120  RwLock& operator=(RwLock&& other) = delete;
121 
122  bool ReadLock();
123  bool TryReadLock(int timeout_ms = 0);
124  void ReadUnlock();
125 
126  bool WriteLock();
127  bool TryWriteLock(int timeout_ms = 0);
128  void WriteUnlock();
129 
130  etcpal_rwlock_t& get();
131 
132 private:
133  etcpal_rwlock_t rwlock_{};
134 };
135 
138 {
139  (void)etcpal_rwlock_create(&rwlock_);
140 }
141 
144 {
145  etcpal_rwlock_destroy(&rwlock_);
146 }
147 
150 inline bool RwLock::ReadLock()
151 {
152  return etcpal_rwlock_readlock(&rwlock_);
153 }
154 
166 inline bool RwLock::TryReadLock(int timeout_ms)
167 {
168  return etcpal_rwlock_timed_readlock(&rwlock_, timeout_ms);
169 }
170 
174 inline void RwLock::ReadUnlock()
175 {
176  etcpal_rwlock_readunlock(&rwlock_);
177 }
178 
181 inline bool RwLock::WriteLock()
182 {
183  return etcpal_rwlock_writelock(&rwlock_);
184 }
185 
197 inline bool RwLock::TryWriteLock(int timeout_ms)
198 {
199  return etcpal_rwlock_timed_writelock(&rwlock_, timeout_ms);
200 }
201 
205 inline void RwLock::WriteUnlock()
206 {
207  etcpal_rwlock_writeunlock(&rwlock_);
208 }
209 
212 {
213  return rwlock_;
214 }
215 
232 {
233 public:
234  explicit ReadGuard(RwLock& rwlock);
235  explicit ReadGuard(etcpal_rwlock_t& rwlock);
236  ~ReadGuard();
237 
238  ReadGuard(const ReadGuard& other) = delete;
239  ReadGuard& operator=(const ReadGuard& other) = delete;
240  ReadGuard(ReadGuard&& other) = delete;
241  ReadGuard& operator=(ReadGuard&& other) = delete;
242 
243 private:
244  etcpal_rwlock_t& rwlock_;
245 
246  void GetReadLock();
247 };
248 
251 inline ReadGuard::ReadGuard(RwLock& rwlock) : rwlock_(rwlock.get())
252 {
253  GetReadLock();
254 }
255 
258 inline ReadGuard::ReadGuard(etcpal_rwlock_t& rwlock) : rwlock_(rwlock)
259 {
260  GetReadLock();
261 }
262 
265 {
266  etcpal_rwlock_readunlock(&rwlock_);
267 }
268 
269 inline void ReadGuard::GetReadLock()
270 {
271  if (!etcpal_rwlock_readlock(&rwlock_))
272  ETCPAL_THROW(std::runtime_error("etcpal_rwlock_readlock failed."));
273 }
274 
291 {
292 public:
293  explicit WriteGuard(RwLock& rwlock);
294  explicit WriteGuard(etcpal_rwlock_t& rwlock);
295  ~WriteGuard();
296 
297  WriteGuard(const WriteGuard& other) = delete;
298  WriteGuard& operator=(const WriteGuard& other) = delete;
299  WriteGuard(WriteGuard&& other) = delete;
300  WriteGuard& operator=(WriteGuard&& other) = delete;
301 
302 private:
303  etcpal_rwlock_t& rwlock_;
304 
305  void GetWriteLock();
306 };
307 
310 inline WriteGuard::WriteGuard(RwLock& rwlock) : rwlock_(rwlock.get())
311 {
312  GetWriteLock();
313 }
314 
317 inline WriteGuard::WriteGuard(etcpal_rwlock_t& rwlock) : rwlock_(rwlock)
318 {
319  GetWriteLock();
320 }
321 
324 {
325  etcpal_rwlock_writeunlock(&rwlock_);
326 }
327 
328 inline void WriteGuard::GetWriteLock()
329 {
330  if (!etcpal_rwlock_writelock(&rwlock_))
331  ETCPAL_THROW(std::runtime_error("etcpal_rwlock_writelock failed."));
332 }
333 
334 }; // namespace etcpal
335 
336 #endif // ETCPAL_CPP_RWLOCK_H_
Read lock guard around a read-write lock.
Definition: rwlock.h:232
ReadGuard(RwLock &rwlock)
Lock an etcpal::RwLock for reading.
Definition: rwlock.h:251
~ReadGuard()
Release the read lock upon going out-of-scope.
Definition: rwlock.h:264
A wrapper class for the EtcPal read-write lock type.
Definition: rwlock.h:112
bool WriteLock()
Access the read-write lock for writing.
Definition: rwlock.h:181
etcpal_rwlock_t & get()
Get a reference to the underlying etcpal_rwlock_t type.
Definition: rwlock.h:211
void ReadUnlock()
Release a read lock on the read-write lock.
Definition: rwlock.h:174
~RwLock()
Destroy the read-write lock.
Definition: rwlock.h:143
void WriteUnlock()
Release a write lock on the read-write lock.
Definition: rwlock.h:205
bool TryReadLock(int timeout_ms=0)
Try to access the read-write lock for reading.
Definition: rwlock.h:166
RwLock()
Create a new read-write lock.
Definition: rwlock.h:137
bool TryWriteLock(int timeout_ms=0)
Try to access the read-write lock for writing.
Definition: rwlock.h:197
bool ReadLock()
Access the read-write lock for reading.
Definition: rwlock.h:150
Write lock guard around a read-write lock.
Definition: rwlock.h:291
WriteGuard(RwLock &rwlock)
Lock an etcpal::RwLock for writing.
Definition: rwlock.h:310
~WriteGuard()
Release the write lock upon going out-of-scope.
Definition: rwlock.h:323
Common definitions used by EtcPal C++ wrappers.
bool etcpal_rwlock_timed_writelock(etcpal_rwlock_t *id, int timeout_ms)
Try to access a read-write lock for writing, giving up after a timeout.
void etcpal_rwlock_destroy(etcpal_rwlock_t *id)
Destroy a read-write lock object.
void etcpal_rwlock_readunlock(etcpal_rwlock_t *id)
Release a read lock on a read-write lock object.
PLATFORM_DEFINED etcpal_rwlock_t
The read-write lock identifier.
Definition: rwlock.dox:79
bool etcpal_rwlock_create(etcpal_rwlock_t *id)
Create a new read-write lock.
void etcpal_rwlock_writeunlock(etcpal_rwlock_t *id)
Release a write lock on a read-write lock object.
bool etcpal_rwlock_readlock(etcpal_rwlock_t *id)
Access a read-write lock for reading.
bool etcpal_rwlock_writelock(etcpal_rwlock_t *id)
Access a read-write lock for writing.
bool etcpal_rwlock_timed_readlock(etcpal_rwlock_t *id, int timeout_ms)
Try to access a read-write lock for reading, giving up after a timeout.