From 98df4b50b2892ffd27614f495119960452505aad Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Sun, 21 Jul 2024 17:22:22 -0600 Subject: [PATCH] Introduce TaskResult::empty(). --- include/deal.II/base/task_result.h | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/deal.II/base/task_result.h b/include/deal.II/base/task_result.h index 478a3a8fc0..abbc6f8ade 100644 --- a/include/deal.II/base/task_result.h +++ b/include/deal.II/base/task_result.h @@ -337,6 +337,15 @@ namespace Threads const T & value() const; + /** + * Return whether the object has an associated task result object or not. + * Only objects that are default-initialized, or for which clear() has + * been called, or that have been moved from, will return `true` in + * this function. + */ + bool + empty() const; + private: /** * An atomic flag that allows us to test whether the task has finished @@ -504,6 +513,35 @@ namespace Threads + template + inline bool + TaskResult::empty() const + { + // If we have waited before, then return immediately: + if (result_is_available) + return false; + else + // If we have not waited, wait now. We need to use the double-checking + // pattern to ensure that if two threads get to this place at the same + // time, one returns right away while the other does the work. Note + // that this happens under the lock, so only one thread gets to be in + // this code block at the same time: + { + std::lock_guard lock(mutex); + if (result_is_available) + return false; + else + // If there is a task, then this object is not empty. Otherwise, we + // have no result and no task, so the object is empty: + if (task.has_value()) + return false; + else + return true; + } + } + + + template inline const T & TaskResult::value() const -- 2.39.5