Commit | Line | Data |
---|---|---|
a3a56255 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_LOCKED_REFERENCE_H | |
9 | #define LTTNG_LOCKED_REFERENCE_H | |
10 | ||
11 | #define _LGPL_SOURCE | |
12 | #include <mutex> | |
13 | ||
14 | namespace lttng { | |
15 | ||
16 | /* | |
17 | * A locked reference is useful to return a reference to an object | |
18 | * while ensuring that the caller uses it within a given locking context. | |
19 | * | |
20 | * For instance, a number of look-up APIs return an object and require the | |
21 | * caller to hold the RCU reader lock for the duration of their use of the | |
22 | * return value. | |
23 | * | |
24 | * Using a locked_reference, a function returning such an object can: | |
25 | * - acquire the rcu read lock using a unique_read_lock, | |
26 | * - perform its look-up | |
27 | * - return a reference to which the unique_read_lock is transferred. | |
28 | * | |
29 | * Note that this locked reference can be used like a pointer | |
30 | * (see operators `*` and `->`). However, note that it is a _reference_. | |
31 | * Hence, _it can't be null_. | |
32 | * | |
33 | * Functions returning this type will most likely throw an exception | |
34 | * when the look-up fails. | |
35 | */ | |
36 | template <class WrappedType, class UniqueLockType> | |
37 | class locked_reference { | |
38 | public: | |
39 | locked_reference(WrappedType& value, UniqueLockType&& lock) : | |
40 | _value(value), _lock(std::move(lock)) | |
41 | { | |
42 | } | |
43 | ||
44 | WrappedType& operator*() const | |
45 | { | |
46 | return _value; | |
47 | } | |
48 | ||
49 | WrappedType* operator->() const | |
50 | { | |
51 | return &_value; | |
52 | } | |
53 | ||
54 | private: | |
55 | WrappedType& _value; | |
56 | UniqueLockType _lock; | |
57 | }; | |
58 | ||
59 | } /* namespace lttng */ | |
60 | ||
61 | #endif /* LTTNG_LOCKED_REFERENCE_H */ |