Only check for wrongly finished async traversals in debug mode

This commit is contained in:
Denis Blank 2018-02-05 22:49:55 +01:00
parent 62823f8f56
commit cd2af2d49a

View File

@ -32,6 +32,7 @@
#define CONTINUABLE_DETAIL_PACK_TRAVERSAL_ASYNC_HPP_INCLUDED #define CONTINUABLE_DETAIL_PACK_TRAVERSAL_ASYNC_HPP_INCLUDED
#include <atomic> #include <atomic>
#include <cassert>
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
@ -105,7 +106,10 @@ auto make_resume_traversal_callable(Frame&& frame, State&& state)
template <typename Visitor, typename... Args> template <typename Visitor, typename... Args>
class async_traversal_frame : public Visitor { class async_traversal_frame : public Visitor {
tuple<Args...> args_; tuple<Args...> args_;
#ifndef _NDEBUG
std::atomic<bool> finished_; std::atomic<bool> finished_;
#endif // _NDEBUG
Visitor& visitor() noexcept { Visitor& visitor() noexcept {
return *static_cast<Visitor*>(this); return *static_cast<Visitor*>(this);
@ -117,13 +121,17 @@ class async_traversal_frame : public Visitor {
public: public:
explicit async_traversal_frame(Visitor visitor, Args... args) explicit async_traversal_frame(Visitor visitor, Args... args)
: Visitor(std::move(visitor)), : Visitor(std::move(visitor)), args_(util::make_tuple(std::move(args)...))
args_(util::make_tuple(std::move(args)...)), finished_(false) { #ifndef _NDEBUG
,
finished_(false)
#endif // _NDEBUG
{
} }
/// We require a virtual base /// We require a virtual base
~async_traversal_frame() override { ~async_traversal_frame() override {
HPX_ASSERT(finished_); assert(finished_.load());
} }
template <typename MapperArg> template <typename MapperArg>
@ -169,10 +177,14 @@ public:
/// Calls the visitor with no arguments to signalize that the /// Calls the visitor with no arguments to signalize that the
/// asynchronous traversal was finished. /// asynchronous traversal was finished.
void async_complete() { void async_complete() {
#ifndef _NDEBUG
{
bool expected = false; bool expected = false;
if (finished_.compare_exchange_strong(expected, true)) { assert(finished_.compare_exchange_strong(expected, true));
util::invoke(visitor(), async_traverse_complete_tag{}, std::move(args_));
} }
#endif // _NDEBUG
visitor()(async_traverse_complete_tag{}, std::move(args_));
} }
}; };
@ -291,7 +303,7 @@ public:
// Abort the current control flow // Abort the current control flow
void detach() noexcept { void detach() noexcept {
HPX_ASSERT(!detached_); assert(!detached_);
detached_ = true; detached_ = true;
} }