Commit | Line | Data |
---|---|---|
0a325f4d JG |
1 | /* |
2 | * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: LGPL-2.1-only | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef LTTNG_PTHREAD_LOCK_H | |
9 | #define LTTNG_PTHREAD_LOCK_H | |
10 | ||
11 | #include <common/exception.hpp> | |
12 | ||
0a325f4d | 13 | #include <mutex> |
28f23191 | 14 | #include <pthread.h> |
0a325f4d JG |
15 | |
16 | namespace lttng { | |
17 | namespace pthread { | |
18 | ||
19 | namespace details { | |
20 | /* | |
21 | * Class wrapping pthread mutexes and satisfying the Mutex named requirements, except | |
22 | * for the "Default Constructible" requirement. The class is not default-constructible since the | |
23 | * intention is to ease the transition of existing C-code using pthread mutexes to idiomatic C++. | |
24 | * | |
25 | * New code should use std::mutex. | |
26 | */ | |
27 | class mutex { | |
28 | public: | |
5e3b23be | 29 | explicit mutex(pthread_mutex_t& mutex_p) : _mutex(mutex_p) |
0a325f4d JG |
30 | { |
31 | } | |
32 | ||
9d89db29 JG |
33 | ~mutex() = default; |
34 | ||
0a325f4d | 35 | /* "Not copyable" and "not moveable" Mutex requirements. */ |
9d89db29 JG |
36 | mutex(mutex const&) = delete; |
37 | mutex(mutex&&) = delete; | |
38 | mutex& operator=(mutex const&) = delete; | |
39 | mutex& operator=(mutex&&) = delete; | |
0a325f4d JG |
40 | |
41 | void lock() | |
42 | { | |
43 | if (pthread_mutex_lock(&_mutex) != 0) { | |
44 | LTTNG_THROW_POSIX("Failed to lock mutex", errno); | |
45 | } | |
46 | } | |
47 | ||
48 | bool try_lock() | |
49 | { | |
50 | const auto ret = pthread_mutex_trylock(&_mutex); | |
51 | ||
52 | if (ret == 0) { | |
53 | return true; | |
54 | } else if (errno == EBUSY || errno == EAGAIN) { | |
55 | return false; | |
56 | } else { | |
57 | LTTNG_THROW_POSIX("Failed to try to lock mutex", errno); | |
58 | } | |
59 | } | |
60 | ||
61 | void unlock() | |
62 | { | |
63 | if (pthread_mutex_unlock(&_mutex) != 0) { | |
460bede7 JG |
64 | /* |
65 | * Unlock cannot throw as it is called as part of lock_guard's destructor. | |
66 | */ | |
67 | abort(); | |
0a325f4d JG |
68 | } |
69 | } | |
70 | ||
71 | private: | |
72 | pthread_mutex_t& _mutex; | |
73 | }; | |
74 | } /* namespace details */ | |
75 | ||
76 | /* | |
77 | * Provides the basic concept of std::lock_guard for posix mutexes. | |
78 | * | |
79 | * `lock` is held for the duration of lock_guard's lifetime. | |
80 | */ | |
81 | class lock_guard { | |
82 | public: | |
5e3b23be | 83 | explicit lock_guard(pthread_mutex_t& mutex) : _mutex(mutex), _guard(_mutex) |
0a325f4d JG |
84 | { |
85 | } | |
86 | ||
9d89db29 JG |
87 | ~lock_guard() = default; |
88 | ||
89 | lock_guard(const lock_guard&) = delete; | |
90 | lock_guard(lock_guard&&) = delete; | |
91 | lock_guard& operator=(const lock_guard&) = delete; | |
92 | lock_guard& operator=(lock_guard&&) = delete; | |
0a325f4d JG |
93 | |
94 | private: | |
95 | details::mutex _mutex; | |
96 | std::lock_guard<details::mutex> _guard; | |
97 | }; | |
98 | ||
99 | } /* namespace pthread */ | |
100 | } /* namespace lttng */ | |
101 | ||
102 | #endif /* LTTNG_PTHREAD_LOCK_H */ |