#include <vector>
-namespace simgrid::s4u {
+namespace simgrid {
+
+extern template class XBT_PUBLIC xbt::Extendable<s4u::ActivitySet>;
+
+namespace s4u {
/** @brief ActivitiesSet
*
* This class is a container of activities, allowing to wait for the completion of any or all activities in the set.
* activities.
*/
class XBT_PUBLIC ActivitySet : public xbt::Extendable<ActivitySet> {
- std::vector<ActivityPtr>
- activities_; // We use a vector instead of a set to improve reproductibility accross architectures
+ std::atomic_int_fast32_t refcount_{1};
+ std::vector<ActivityPtr> activities_; // Use vectors, not sets for better reproductibility accross architectures
std::vector<ActivityPtr> failed_activities_;
+ void handle_failed_activities();
+
public:
ActivitySet() = default;
ActivitySet(const std::vector<ActivityPtr> init) : activities_(init) {}
/** Wait for the completion of all activities in the set, but not longer than the provided timeout
*
- * On timeout, an exception is raised, and the completed activities remain in the set. Use test_any() to retrieve
- * them.
+ * On timeout, an exception is raised.
*
- * When no timeout occures, the set is emptied.
+ * In any case, the completed activities remain in the set. Use test_any() to retrieve them.
*/
void wait_all_for(double timeout);
- /** Wait for the completion of all activities in the set. The set is emptied afterward. */
+ /** Wait for the completion of all activities in the set. The set is NOT emptied afterward. */
void wait_all() { wait_all_for(-1); }
/** Returns the first terminated activity if any, or ActivityPtr(nullptr) if no activity is terminated */
ActivityPtr test_any();
*/
ActivityPtr wait_any() { return wait_any_for(-1); }
+ /** Return one of the failed activity of the set that was revealed during the previous wait operation, or
+ * ActivityPtr() if no failed activity exist in the set. */
ActivityPtr get_failed_activity();
+ /** Return whether the set contains any failed activity. */
bool has_failed_activities() { return not failed_activities_.empty(); }
+
+ // boost::intrusive_ptr<ActivitySet> support:
+ friend void intrusive_ptr_add_ref(ActivitySet* as)
+ {
+ XBT_ATTRIB_UNUSED auto previous = as->refcount_.fetch_add(1);
+ xbt_assert(previous != 0);
+ }
+
+ friend void intrusive_ptr_release(ActivitySet* as)
+ {
+ if (as->refcount_.fetch_sub(1) == 1)
+ delete as;
+ }
};
-}; // namespace simgrid::s4u
+} // namespace s4u
+} // namespace simgrid
#endif