#ifndef CAFFE2_NET_ASYNC_TASK_FUTURE_H #define CAFFE2_NET_ASYNC_TASK_FUTURE_H #include #include #include #include #include #include #include namespace caffe2 { // Represents the state of AsyncTask execution, that can be queried with // IsCompleted/IsFailed. Callbacks are supported through SetCallback and // are called upon future's completion. class AsyncTaskFuture { public: AsyncTaskFuture(); // Creates a future completed when all given futures are completed explicit AsyncTaskFuture(const std::vector& futures); ~AsyncTaskFuture(); AsyncTaskFuture(const AsyncTaskFuture&) = delete; AsyncTaskFuture& operator=(const AsyncTaskFuture&) = delete; bool IsCompleted() const; bool IsFailed() const; std::string ErrorMessage() const; void Wait() const; void SetCallback(std::function callback); void SetCompleted(const char* err_msg = nullptr); void ResetState(); private: mutable std::mutex mutex_; mutable std::condition_variable cv_completed_; std::atomic completed_; std::atomic failed_; std::string err_msg_; std::vector> callbacks_; struct ParentCounter { explicit ParentCounter(int init_parent_count) : init_parent_count_(init_parent_count), parent_count(init_parent_count), parent_failed(false) {} void Reset() { std::unique_lock lock(err_mutex); parent_count = init_parent_count_; parent_failed = false; err_msg = ""; } const int init_parent_count_; std::atomic parent_count; std::mutex err_mutex; std::atomic parent_failed; std::string err_msg; }; std::unique_ptr parent_counter_; }; } // namespace caffe2 #endif // CAFFE2_NET_ASYNC_TASK_FUTURE_H