From a3a562552968a6d6787366d6e61ab3d35863fd5a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 16 May 2022 17:50:08 -0400 Subject: [PATCH] Add lttng::locked_reference MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A locked reference is a wrapper that allows functions to return a protected/synchronized version of an object. My immediate use-case for this helper is making it easier to call functions that return an rcu-protected object (require the caller to hold the RCU reader lock for the duration of its use of that object) in an exception safe manner. As such, these functions can now return lttng::locked_reference which ensures the RCU reader lock is held for as long as the object is used. Signed-off-by: Jérémie Galarneau Change-Id: I9f4b7f918ba01491d3de14a1a570c83586f407ae --- src/common/Makefile.am | 1 + src/common/locked-reference.hpp | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/common/locked-reference.hpp diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 23d33e983..66ab77d05 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -88,6 +88,7 @@ libcommon_lgpl_la_SOURCES = \ format.hpp \ kernel-probe.cpp \ location.cpp \ + locked-reference.hpp \ log-level-rule.cpp \ make-unique.hpp \ make-unique-wrapper.hpp \ diff --git a/src/common/locked-reference.hpp b/src/common/locked-reference.hpp new file mode 100644 index 000000000..e0ff3f280 --- /dev/null +++ b/src/common/locked-reference.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_LOCKED_REFERENCE_H +#define LTTNG_LOCKED_REFERENCE_H + +#define _LGPL_SOURCE +#include + +namespace lttng { + +/* + * A locked reference is useful to return a reference to an object + * while ensuring that the caller uses it within a given locking context. + * + * For instance, a number of look-up APIs return an object and require the + * caller to hold the RCU reader lock for the duration of their use of the + * return value. + * + * Using a locked_reference, a function returning such an object can: + * - acquire the rcu read lock using a unique_read_lock, + * - perform its look-up + * - return a reference to which the unique_read_lock is transferred. + * + * Note that this locked reference can be used like a pointer + * (see operators `*` and `->`). However, note that it is a _reference_. + * Hence, _it can't be null_. + * + * Functions returning this type will most likely throw an exception + * when the look-up fails. + */ +template +class locked_reference { +public: + locked_reference(WrappedType& value, UniqueLockType&& lock) : + _value(value), _lock(std::move(lock)) + { + } + + WrappedType& operator*() const + { + return _value; + } + + WrappedType* operator->() const + { + return &_value; + } + +private: + WrappedType& _value; + UniqueLockType _lock; +}; + +} /* namespace lttng */ + +#endif /* LTTNG_LOCKED_REFERENCE_H */ -- 2.34.1