From d38e5b7b70a4282482d9ec11b18a48e02552d476 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Tue, 9 Jun 2020 19:51:27 -0500 Subject: [PATCH] ThreadLocalStorage: add copy and move constructors Add copy and move constructors and corresponding copy and move assignment operators. --- include/deal.II/base/thread_local_storage.h | 79 ++++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/include/deal.II/base/thread_local_storage.h b/include/deal.II/base/thread_local_storage.h index 78afb0a138..923712e90a 100644 --- a/include/deal.II/base/thread_local_storage.h +++ b/include/deal.II/base/thread_local_storage.h @@ -112,6 +112,17 @@ namespace Threads */ ThreadLocalStorage() = default; + /** + * Copy constructor. + */ + ThreadLocalStorage(const ThreadLocalStorage &); + + /** + * Move constructor. The constructor moves all internal data structures + * from the argument. + */ + ThreadLocalStorage(ThreadLocalStorage &&); + /** * A kind of copy constructor. Initializes an internal exemplar by the * given object. The exemplar is in turn used to initialize each thread @@ -127,10 +138,16 @@ namespace Threads explicit ThreadLocalStorage(T &&t); /** - * The copy constructor is deleted. Copying instances of this class is not - * allowed. + * Copy assignment operator. */ - ThreadLocalStorage(const ThreadLocalStorage &t) = delete; + ThreadLocalStorage & + operator=(const ThreadLocalStorage &t); + + /** + * Move assignment operator. + */ + ThreadLocalStorage & + operator=(ThreadLocalStorage &&t); /** * Return a reference to the data stored by this object for the current @@ -253,6 +270,32 @@ namespace Threads { // ----------------- inline and template functions -------------------------- + + template + ThreadLocalStorage::ThreadLocalStorage(const ThreadLocalStorage &t) + : exemplar(t.exemplar) + { + /* + * Raise a reader lock while we are populating our own data in order to + * avoid copying over an invalid state. + */ + std::shared_lock lock(t.insertion_mutex); + data = t.data; + } + + + template + ThreadLocalStorage::ThreadLocalStorage(ThreadLocalStorage &&t) + : exemplar(t.exemplar) + { + /* + * We are nice and raise the writer lock before copying over internal + * data structures from the argument. + */ + std::unique_lock lock(t.insertion_mutex); + data = std::move(t.data); + } + template inline ThreadLocalStorage::ThreadLocalStorage(const T &t) : exemplar(std::make_shared(t)) @@ -265,6 +308,36 @@ namespace Threads {} + template + inline ThreadLocalStorage & + ThreadLocalStorage::operator=(const ThreadLocalStorage &t) + { + /* + * We need to raise the reader lock of the argument and our writer lock + * while copying internal data structures. + */ + std::shared_lock reader_lock(t.insertion_mutex); + std::unique_lock writer_lock(insertion_mutex); + + data = t.data; + } + + + template + inline ThreadLocalStorage & + ThreadLocalStorage::operator=(ThreadLocalStorage &&t) + { + /* + * We need to raise the reader lock of the argument and our writer lock + * while copying internal data structures. + */ + std::shared_lock reader_lock(t.insertion_mutex); + std::unique_lock writer_lock(insertion_mutex); + + data = std::move(t.data); + } + + # ifndef DOXYGEN namespace internal { -- 2.39.5