+size_t Comm::wait_all_for(const std::vector<CommPtr>& comms, double timeout)
+{
+ if (timeout < 0.0) {
+ wait_all(comms);
+ return comms.size();
+ }
+
+ double deadline = Engine::get_clock() + timeout;
+ std::vector<CommPtr> waited_comm(1, nullptr);
+ for (size_t i = 0; i < comms.size(); i++) {
+ double wait_timeout = std::max(0.0, deadline - Engine::get_clock());
+ waited_comm[0] = comms[i];
+ // Using wait_any_for() here (and not wait_for) because we don't want comms to be invalidated on timeout
+ if (wait_any_for(waited_comm, wait_timeout) == -1) {
+ XBT_DEBUG("Timeout (%g): i = %zu", wait_timeout, i);
+ return i;
+ }
+ }
+ return comms.size();
+}
+
+CommPtr Comm::set_source(Host* from)
+{
+ xbt_assert(state_ == State::INITED || state_ == State::STARTING,
+ "Cannot change the source of a Comm once it's started (state: %s)", to_c_str(state_));
+ from_ = from;
+ // Setting 'from_' may allow to start the activity, let's try
+ vetoable_start();
+
+ return this;
+}
+
+CommPtr Comm::set_destination(Host* to)
+{
+ xbt_assert(state_ == State::INITED || state_ == State::STARTING,
+ "Cannot change the destination of a Comm once it's started (state: %s)", to_c_str(state_));
+ to_ = to;
+ // Setting 'to_' may allow to start the activity, let's try
+ vetoable_start();
+
+ return this;
+}
+