From f3c3da02f080a61bfe67c58a79d6a3c6a31de673 Mon Sep 17 00:00:00 2001 From: scott snyder <sss@karma> Date: Thu, 2 Sep 2021 13:25:53 -0400 Subject: [PATCH] CxxUtils: Add LockedPointer. LockedPointer template class, to allow returning a held lock along with a pointer in a movable object. --- Control/CxxUtils/CMakeLists.txt | 2 +- Control/CxxUtils/CxxUtils/LockedPointer.h | 55 +++++++++++++++++++ Control/CxxUtils/share/LockedPointer_test.ref | 2 + Control/CxxUtils/test/LockedPointer_test.cxx | 46 ++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Control/CxxUtils/CxxUtils/LockedPointer.h create mode 100644 Control/CxxUtils/share/LockedPointer_test.ref create mode 100644 Control/CxxUtils/test/LockedPointer_test.cxx diff --git a/Control/CxxUtils/CMakeLists.txt b/Control/CxxUtils/CMakeLists.txt index e7899bebc55c..04e050bf1f22 100644 --- a/Control/CxxUtils/CMakeLists.txt +++ b/Control/CxxUtils/CMakeLists.txt @@ -132,7 +132,7 @@ foreach( test sincos_test ArrayScanner_test Arrayrep_test restrict_test vectorize_test get_unaligned_test aligned_vector_test vec_int_test vec_float_test vec_fb_int_test vec_fb_float_test ConcurrentHashmapImpl_test SimpleUpdater_test hexdump_test - FPControl_test ) + FPControl_test LockedPointer_test ) atlas_add_test( ${test} SOURCES test/${test}.cxx LOG_IGNORE_PATTERN "no version information available" diff --git a/Control/CxxUtils/CxxUtils/LockedPointer.h b/Control/CxxUtils/CxxUtils/LockedPointer.h new file mode 100644 index 000000000000..efccbc849919 --- /dev/null +++ b/Control/CxxUtils/CxxUtils/LockedPointer.h @@ -0,0 +1,55 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. +/* + * Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration. + */ +/** + * @file CxxUtils/LockedPointer.h + * @author scott snyder <snyder@bnl.gov> + * @date Sep, 2021 + * @brief A pointer together with a movable lock. + */ + + +#ifndef CXXUTILS_LOCKEDPOINTER_H +#define CXXUTILS_LOCKEDPOINTER_H + + +#include <mutex> + + +namespace CxxUtils { + + +/** + * @brief A pointer together with a movable lock. + * + * This class holds a pointer to T along with a unique_lock. + * It can be used where we want to return a pointer to an object + * protected by a lock, and so want to return the lock along + * with the pointer. + * + * Objects of this class may be moved but not copied (like unique_ptr). + */ +template <class T, class MUTEX=std::recursive_mutex> +class LockedPointer +{ +public: + LockedPointer (T& p, std::unique_lock<MUTEX>&& lock) + : m_lock (std::move (lock)), + m_p (p) + { + } + + T* get() { return &m_p; } + T* operator->() { return &m_p; } + T& operator*() { return m_p; } + +private: + std::unique_lock<MUTEX> m_lock; + T& m_p; +}; + +} // namespace CxxUtils + + +#endif // not CXXUTILS_LOCKEDPOINTER_H diff --git a/Control/CxxUtils/share/LockedPointer_test.ref b/Control/CxxUtils/share/LockedPointer_test.ref new file mode 100644 index 000000000000..562d2b65fa11 --- /dev/null +++ b/Control/CxxUtils/share/LockedPointer_test.ref @@ -0,0 +1,2 @@ +CxxUtils/LockedPointer_test +test1 diff --git a/Control/CxxUtils/test/LockedPointer_test.cxx b/Control/CxxUtils/test/LockedPointer_test.cxx new file mode 100644 index 000000000000..531d71d9106e --- /dev/null +++ b/Control/CxxUtils/test/LockedPointer_test.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ +/** + * @file CxxUtils/test/LockedPointer_test.cxx + * @author scott snyder + * @date Sep 2021 + * @brief Regression tests for LockedPointer. + */ + + +#undef NDEBUG +#include "CxxUtils/LockedPointer.h" +#include <mutex> +#include <iostream> +#include <cassert> + + +void test1a (CxxUtils::LockedPointer<int> p) +{ + assert (*p == 42); +} + +void test1() +{ + std::cout << "test1\n"; + + std::recursive_mutex m; + int x = 42; + + { + std::unique_lock l (m); + CxxUtils::LockedPointer<int> p (x, std::move(l)); + assert (*p == 42); + assert (*p.get() == 42); + test1a (std::move (p)); + } +} + + +int main() +{ + std::cout << "CxxUtils/LockedPointer_test\n"; + test1(); + return 0; +} -- GitLab