diff --git a/libs/core/errors/include/hpx/errors/exception_list.hpp b/libs/core/errors/include/hpx/errors/exception_list.hpp index fd115db38db..bd7327ccf31 100644 --- a/libs/core/errors/include/hpx/errors/exception_list.hpp +++ b/libs/core/errors/include/hpx/errors/exception_list.hpp @@ -26,7 +26,7 @@ namespace hpx { /// The class exception_list is a container of exception_ptr objects /// parallel algorithms may use to communicate uncaught exceptions - /// encountered during parallel execution to the caller of the algorithm + /// encountered during parallel execution to the caller of the algorithm. /// /// The type exception_list::const_iterator fulfills the requirements of /// a forward iterator. @@ -34,73 +34,107 @@ namespace hpx { class HPX_CORE_EXPORT exception_list : public hpx::exception { private: - /// \cond NOINTERNAL - - // TODO: Does this need to be hpx::spinlock? - // typedef hpx::spinlock mutex_type; - // TODO: Add correct initialization of hpx::util::detail spinlock. using mutex_type = hpx::util::detail::spinlock; - using exception_list_type = std::list; + exception_list_type exceptions_; mutable mutex_type mtx_; - void add_no_lock(std::exception_ptr const& e); - /// \endcond + // Adds an exception to the list without acquiring a lock + void add_no_lock(std::exception_ptr const& e) + { + exceptions_.push_back(e); + } public: - /// bidirectional iterator using iterator = exception_list_type::const_iterator; - /// \cond NOINTERNAL - // \throws nothing ~exception_list() noexcept override = default; - exception_list(); - explicit exception_list(std::exception_ptr const& e); - explicit exception_list(exception_list_type&& l); + exception_list() = default; + + explicit exception_list(std::exception_ptr const& e) + { + add(e); + } + + explicit exception_list(exception_list_type&& l) + { + std::lock_guard lock(mtx_); + exceptions_ = std::move(l); + } + + exception_list(exception_list const& l) : hpx::exception(l) + { + std::lock_guard lock(l.mtx_); + exceptions_ = l.exceptions_; + } + + exception_list(exception_list&& l) noexcept : hpx::exception(std::move(l)) + { + std::lock_guard l_lock(l.mtx_); + exceptions_ = std::move(l.exceptions_); + } - exception_list(exception_list const& l); - exception_list(exception_list&& l) noexcept; + exception_list& operator=(exception_list const& l) + { + if (this != &l) { + std::lock_guard this_lock(mtx_); + std::lock_guard l_lock(l.mtx_); + exceptions_ = l.exceptions_; + } + return *this; + } - exception_list& operator=(exception_list const& l); - exception_list& operator=(exception_list&& l) noexcept; + exception_list& operator=(exception_list&& l) noexcept + { + if (this != &l) { + std::lock_guard this_lock(mtx_); + std::lock_guard l_lock(l.mtx_); + exceptions_ = std::move(l.exceptions_); + } + return *this; + } - /// - void add(std::exception_ptr const& e); - /// \endcond + // Adds an exception to the list in a thread-safe manner + void add(std::exception_ptr const& e) + { + std::lock_guard lock(mtx_); + add_no_lock(e); + } - /// The number of exception_ptr objects contained within the - /// exception_list. - /// - /// \note Complexity: Constant time. + /// Returns the number of exception_ptr objects in the exception_list. + /// Complexity: Constant time. [[nodiscard]] std::size_t size() const noexcept { - std::lock_guard l(mtx_); + std::lock_guard lock(mtx_); return exceptions_.size(); } - /// An iterator referring to the first exception_ptr object contained - /// within the exception_list. + /// Returns an iterator referring to the first exception_ptr object. [[nodiscard]] exception_list_type::const_iterator begin() const noexcept { - std::lock_guard l(mtx_); + std::lock_guard lock(mtx_); return exceptions_.begin(); } - /// An iterator which is the past-the-end value for the exception_list. + /// Returns a past-the-end iterator for the exception_list. [[nodiscard]] exception_list_type::const_iterator end() const noexcept { - std::lock_guard l(mtx_); + std::lock_guard lock(mtx_); return exceptions_.end(); } - /// \cond NOINTERNAL - [[nodiscard]] std::error_code get_error_code() const; + [[nodiscard]] std::error_code get_error_code() const + { + return std::error_code(); // Placeholder implementation + } - [[nodiscard]] std::string get_message() const; - /// \endcond + [[nodiscard]] std::string get_message() const + { + return "Exception occurred"; // Placeholder implementation + } }; -} // namespace hpx +} // namespace hpx #include