friend kernel::activity::ActivityImpl;
friend std::vector<ActivityPtr> create_DAG_from_dot(const std::string& filename);
friend std::vector<ActivityPtr> create_DAG_from_DAX(const std::string& filename);
+ friend std::vector<ActivityPtr> create_DAG_from_json(const std::string& filename);
#endif
public:
bool has_no_successor() const { return successors_.empty(); }
const std::set<ActivityPtr>& get_dependencies() const { return dependencies_; }
const std::vector<ActivityPtr>& get_successors() const { return successors_; }
+ virtual void fire_this_completion() const = 0;
protected:
Activity() = default;
XBT_CVERB(s4u_activity, "Remove a dependency from '%s' on '%s'", get_cname(), b->get_cname());
b->dependencies_.erase(this);
if (b->dependencies_solved()) {
- b->vetoable_start();
+ b->start();
}
successors_.pop_back();
}
private:
static xbt::signal<void(Activity&)> on_veto;
- static xbt::signal<void(Activity const&)> on_completion;
- static xbt::signal<void(Activity const&)> on_suspended;
- static xbt::signal<void(Activity const&)> on_resumed;
+ static xbt::signal<void(Activity const&)> on_suspend;
+ static xbt::signal<void(Activity const&)> on_resume;
public:
/*! Add a callback fired each time that the activity fails to start because of a veto (e.g., unsolved dependency or no
* resource assigned) */
static void on_veto_cb(const std::function<void(Activity&)>& cb) { on_veto.connect(cb); }
- /*! Add a callback fired when the activity completes (either normally, cancelled or failed) */
- static void on_completion_cb(const std::function<void(Activity const&)>& cb) { on_completion.connect(cb); }
/*! Add a callback fired when the activity is suspended */
- static void on_suspended_cb(const std::function<void(Activity const&)>& cb) { on_suspended.connect(cb); }
+ static void on_suspend_cb(const std::function<void(Activity const&)>& cb)
+ {
+ on_suspend.connect(cb);
+ }
/*! Add a callback fired when the activity is resumed after being suspended */
- static void on_resumed_cb(const std::function<void(Activity const&)>& cb) { on_resumed.connect(cb); }
+ static void on_resume_cb(const std::function<void(Activity const&)>& cb)
+ {
+ on_resume.connect(cb);
+ }
+
+ XBT_ATTRIB_DEPRECATED_v334("Please use on_suspend_cb() instead") static void on_suspended_cb(
+ const std::function<void(Activity const&)>& cb)
+ {
+ on_suspend.connect(cb);
+ }
+ XBT_ATTRIB_DEPRECATED_v334("Please use on_resume_cb() instead") static void on_resumed_cb(
+ const std::function<void(Activity const&)>& cb)
+ {
+ on_resume.connect(cb);
+ }
- void vetoable_start()
+ XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") void vetoable_start()
+ {
+ start();
+ }
+ void start()
{
state_ = State::STARTING;
if (dependencies_solved() && is_assigned()) {
XBT_CVERB(s4u_activity, "'%s' is assigned to a resource and all dependencies are solved. Let's start", get_cname());
- start();
+ do_start();
} else {
if (vetoed_activities_ != nullptr)
vetoed_activities_->insert(this);
void complete(Activity::State state)
{
+ // Ensure that the current activity remains alive until the end of the function, even if its last reference is
+ // released by the on_completion() callbacks.
+ ActivityPtr keepalive(this);
state_ = state;
- on_completion(*this);
+ fire_this_completion();
if (state == State::FINISHED)
release_dependencies();
}
*
* This function is optional: you can call wait() even if you didn't call start()
*/
- virtual Activity* start() = 0;
+ virtual Activity* do_start() = 0;
/** Tests whether the given activity is terminated yet. */
virtual bool test();
/*! take a vector s4u::ActivityPtr and return the rank of the first finished one (or -1 if none is done). */
std::string tracing_category_ = "";
public:
+ inline static xbt::signal<void(AnyActivity const&)> on_completion;
+ /*! Add a callback fired when the activity completes (either normally, cancelled or failed) */
+ static void on_completion_cb(const std::function<void(AnyActivity const&)>& cb) { on_completion.connect(cb); }
+
AnyActivity* add_successor(ActivityPtr a)
{
Activity::add_successor(a);
AnyActivity* set_tracing_category(const std::string& category)
{
- xbt_assert(get_state() == State::INITED, "Cannot change the tracing category of an activity after its start");
+ xbt_assert(get_state() == State::INITED || get_state() == State::STARTING,
+ "Cannot change the tracing category of an activity after its start");
tracing_category_ = category;
return static_cast<AnyActivity*>(this);
}
{
return get_data<void>();
}
-
- AnyActivity* vetoable_start()
+ XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") AnyActivity* vetoable_start()
+ {
+ return start();
+ }
+ AnyActivity* start()
{
- Activity::vetoable_start();
+ Activity::start();
return static_cast<AnyActivity*>(this);
}
AnyActivity* cancel() { return static_cast<AnyActivity*>(Activity::cancel()); }
AnyActivity* wait() { return wait_for(-1.0); }
- virtual AnyActivity* wait_for(double timeout) { return static_cast<AnyActivity*>(Activity::wait_for(timeout)); }
+ virtual AnyActivity* wait_for(double timeout) {
+ return static_cast<AnyActivity*>(Activity::wait_for(timeout));
+ }
#ifndef DOXYGEN
/* The refcounting is done in the ancestor class, Activity, but we want each of the classes benefiting of the CRTP