Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
cleaning the actor twice seems somewhat overplayed
[simgrid.git] / src / s4u / s4u_Comm.cpp
index 50eaf00..16b1284 100644 (file)
@@ -6,6 +6,7 @@
 #include "src/msg/msg_private.hpp"
 #include "xbt/log.h"
 
+#include "simgrid/Exception.hpp"
 #include "simgrid/s4u/Comm.hpp"
 #include "simgrid/s4u/Mailbox.hpp"
 
@@ -13,9 +14,9 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm, s4u_activity, "S4U asynchronous commun
 
 namespace simgrid {
 namespace s4u {
-simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> s4u::Comm::on_sender_start;
-simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> s4u::Comm::on_receiver_start;
-simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> s4u::Comm::on_completion;
+xbt::signal<void(ActorPtr)> Comm::on_sender_start;
+xbt::signal<void(ActorPtr)> Comm::on_receiver_start;
+xbt::signal<void(ActorPtr)> Comm::on_completion;
 
 Comm::~Comm()
 {
@@ -31,11 +32,9 @@ Comm::~Comm()
 
 int Comm::wait_any_for(std::vector<CommPtr>* comms, double timeout)
 {
-  std::unique_ptr<simgrid::kernel::activity::CommImpl* []> rcomms(
-      new simgrid::kernel::activity::CommImpl*[comms->size()]);
-  std::transform(begin(*comms), end(*comms), rcomms.get(), [](const CommPtr& comm) {
-    return static_cast<simgrid::kernel::activity::CommImpl*>(comm->pimpl_.get());
-  });
+  std::unique_ptr<kernel::activity::CommImpl* []> rcomms(new kernel::activity::CommImpl*[comms->size()]);
+  std::transform(begin(*comms), end(*comms), rcomms.get(),
+                 [](const CommPtr& comm) { return static_cast<kernel::activity::CommImpl*>(comm->pimpl_.get()); });
   return simcall_comm_waitany(rcomms.get(), comms->size(), timeout);
 }
 
@@ -145,7 +144,7 @@ Comm* Comm::wait_for(double timeout)
 {
   switch (state_) {
     case State::FINISHED:
-      return this;
+      break;
 
     case State::INITED: // It's not started yet. Do it in one simcall
       if (src_buff_ != nullptr) {
@@ -159,13 +158,16 @@ Comm* Comm::wait_for(double timeout)
                           user_data_, timeout, rate_);
       }
       state_ = State::FINISHED;
-      return this;
+      break;
 
     case State::STARTED:
       simcall_comm_wait(pimpl_, timeout);
       on_completion(Actor::self());
       state_ = State::FINISHED;
-      return this;
+      break;
+
+    case State::CANCELED:
+      throw CancelException(XBT_THROW_POINT, "Communication canceled");
 
     default:
       THROW_IMPOSSIBLE;
@@ -174,11 +176,9 @@ Comm* Comm::wait_for(double timeout)
 }
 int Comm::test_any(std::vector<CommPtr>* comms)
 {
-  std::unique_ptr<simgrid::kernel::activity::CommImpl* []> rcomms(
-      new simgrid::kernel::activity::CommImpl*[comms->size()]);
-  std::transform(begin(*comms), end(*comms), rcomms.get(), [](const CommPtr& comm) {
-    return static_cast<simgrid::kernel::activity::CommImpl*>(comm->pimpl_.get());
-  });
+  std::unique_ptr<kernel::activity::CommImpl* []> rcomms(new kernel::activity::CommImpl*[comms->size()]);
+  std::transform(begin(*comms), end(*comms), rcomms.get(),
+                 [](const CommPtr& comm) { return static_cast<kernel::activity::CommImpl*>(comm->pimpl_.get()); });
   return simcall_comm_testany(rcomms.get(), comms->size());
 }
 
@@ -193,7 +193,10 @@ Comm* Comm::detach()
 
 Comm* Comm::cancel()
 {
-  simgrid::simix::simcall([this] { static_cast<kernel::activity::CommImpl*>(pimpl_.get())->cancel(); });
+  simix::simcall([this] {
+    if (pimpl_)
+      boost::static_pointer_cast<kernel::activity::CommImpl>(pimpl_)->cancel();
+  });
   state_ = State::CANCELED;
   return this;
 }
@@ -215,11 +218,16 @@ bool Comm::test()
   return false;
 }
 
-MailboxPtr Comm::get_mailbox()
+Mailbox* Comm::get_mailbox()
 {
   return mailbox_;
 }
 
+ActorPtr Comm::get_sender()
+{
+  return sender_ ? sender_->iface() : nullptr;
+}
+
 void intrusive_ptr_release(simgrid::s4u::Comm* c)
 {
   if (c->refcount_.fetch_sub(1, std::memory_order_release) == 1) {