-}
-void Comm::wait() {
- xbt_assert(state_ == started || state_ == inited);
-
- if (state_ == started)
- simcall_comm_wait(pimpl_, -1/*timeout*/);
- else {// p_state == inited. Save a simcall and do directly a blocking send/recv
- if (srcBuff_ != nullptr) {
- simcall_comm_send(sender_, mailbox_->getImpl(), remains_, rate_,
- srcBuff_, srcBuffSize_,
- matchFunction_, copyDataFunction_,
- userData_, -1 /*timeout*/);
- } else {
- simcall_comm_recv(receiver_, mailbox_->getImpl(), dstBuff_, &dstBuffSize_,
- matchFunction_, copyDataFunction_,
- userData_, -1/*timeout*/, rate_);
- }
+ return this;
+}
+
+/** @brief Block the calling actor until the communication is finished */
+Activity* Comm::wait()
+{
+ return this->wait(-1);
+}
+
+/** @brief Block the calling actor until the communication is finished, or until timeout
+ *
+ * On timeout, an exception is thrown.
+ *
+ * @param timeout the amount of seconds to wait for the comm termination.
+ * Negative values denote infinite wait times. 0 as a timeout returns immediately. */
+Activity* Comm::wait(double timeout)
+{
+ switch (state_) {
+ case finished:
+ return this;
+
+ case inited: // It's not started yet. Do it in one simcall
+ if (srcBuff_ != nullptr) {
+ simcall_comm_send(sender_, mailbox_->getImpl(), remains_, rate_, srcBuff_, srcBuffSize_, matchFunction_,
+ copyDataFunction_, userData_, timeout);
+ } else { // Receiver
+ simcall_comm_recv(receiver_, mailbox_->getImpl(), dstBuff_, &dstBuffSize_, matchFunction_, copyDataFunction_,
+ userData_, timeout, rate_);
+ }
+ state_ = finished;
+ return this;
+
+ case started:
+ simcall_comm_wait(pimpl_, timeout);
+ state_ = finished;
+ return this;
+
+ default:
+ THROW_IMPOSSIBLE;