]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add ThreadLocalStorage::get_for_thread().
authorWolfgang Bangerth <bangerth@colostate.edu>
Wed, 24 Apr 2024 19:56:08 +0000 (13:56 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 24 Apr 2024 22:29:43 +0000 (16:29 -0600)
include/deal.II/base/thread_local_storage.h

index 5919e6b187894a811e33cc65bd8dfdd00d9817d4..7abd759db0f8867067b6535269b3c4f1c710ef16 100644 (file)
@@ -24,6 +24,7 @@
 #  include <map>
 #  include <memory>
 #  include <mutex>
+#  include <optional>
 #  include <shared_mutex>
 #  include <thread>
 #  include <vector>
@@ -175,6 +176,23 @@ namespace Threads
     T &
     get(bool &exists);
 
+    /**
+     * If the thread with given `id` has an object currently stored, then return
+     * it by value via the `std::optional` object. If the indicated thread does
+     * not have an object stored, return an empty `std::optional`.
+     *
+     * Note that in the successful case, this function returns a *copy* of
+     * the object, unlike get() which returns a reference to it. This is
+     * because when you call get(), you are calling it from the current
+     * thread (i.e., the thread that "owns" the object), and so all accesses
+     * are by definition not concurrent. On the other hand, if you are asking
+     * about the object owned by a different thread, that other thread might
+     * concurrently be accessing it and that might cause race conditions.
+     * To avoid these, the function here returns a copy.
+     */
+    std::optional<T>
+    get_for_thread(const std::thread::id &id) const;
+
     /**
      * Conversion operator that simply converts the thread-local object to the
      * data type that it stores. This function is equivalent to calling the
@@ -440,6 +458,23 @@ namespace Threads
   }
 
 
+  template <typename T>
+  std::optional<T>
+  ThreadLocalStorage<T>::get_for_thread(const std::thread::id &id) const
+  {
+    // Take a shared ("reader") lock for lookup:
+    std::shared_lock<decltype(insertion_mutex)> lock(insertion_mutex);
+
+    // Then see whether we can find the indicated object; if so, copy it,
+    // otherwise return an empty std::optional.
+    const auto it = data.find(id);
+    if (it != data.end())
+      return it->second;
+    else
+      return {};
+  }
+
+
   template <typename T>
   inline T &
   ThreadLocalStorage<T>::get()

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.