* it isn't associated with a task, just return.
*/
void
- join();
+ join() const;
/**
* Return a reference to the object computed by the task. This
* A lock object that guards access to all of the `mutable` objects above.
*/
mutable std::mutex mutex;
-
- /**
- * Wait for the task to finish, move its result into the `task_result`
- * object, and then release all information still associated with the
- * task that originally computed the result.
- */
- void
- wait_and_move_result() const;
};
template <typename T>
inline void
- TaskResult<T>::join()
+ TaskResult<T>::join() const
{
// If we have waited before, then return immediately:
if (result_is_available)
if (result_is_available)
return;
else
- // If there is a task, wait for it to finish. We could then move
- // the result, but it's fine to postpone that until someone actually
- // asks for the result.
- if (task.has_value())
+ {
+ // The object is not empty and it has not received its result yet.
+ // So it must have a task object:
+ Assert(task.has_value(), ExcInternalError());
+
task.value().join();
+ task_result = std::move(task.value().return_value());
+ task.reset();
+
+ result_is_available = true;
+ }
}
}
TaskResult<T>::value() const
{
if (!result_is_available)
- wait_and_move_result();
+ join();
return task_result.value();
}
-
-
-
- template <typename T>
- inline void
- TaskResult<T>::wait_and_move_result() const
- {
- // If we have waited before, then return immediately:
- if (result_is_available)
- return;
- 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<std::mutex> lock(mutex);
-
- if (result_is_available)
- return;
- else
- {
- Assert(task.has_value(),
- ExcMessage("You cannot wait for the result of a TaskResult "
- "object that has no task associated with it."));
- task.value().join();
- task_result = std::move(task.value().return_value());
- task.reset();
-
- result_is_available = true;
- }
- }
- }
-
} // namespace Threads
/**