Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of framagit.org:simgrid/simgrid
[simgrid.git] / include / simgrid / s4u / Activity.hpp
index c22a047..506cd3c 100644 (file)
@@ -39,6 +39,7 @@ class XBT_PUBLIC Activity : public xbt::Extendable<Activity> {
   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:
@@ -50,6 +51,7 @@ 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;
@@ -63,7 +65,7 @@ protected:
       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();
     }
@@ -103,27 +105,45 @@ protected:
 
 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);
@@ -133,8 +153,11 @@ public:
 
   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();
   }
@@ -151,7 +174,7 @@ public:
    *
    * 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). */
@@ -233,6 +256,10 @@ template <class AnyActivity> class Activity_T : public Activity {
   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);
@@ -253,7 +280,8 @@ public:
 
   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);
   }
@@ -269,16 +297,21 @@ public:
   {
     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