Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Eventually, OOP is really good.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Mon, 28 Feb 2022 10:10:32 +0000 (11:10 +0100)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Mon, 28 Feb 2022 13:26:09 +0000 (14:26 +0100)
Improved version of commit f4925bd65c467da9862149984960de961af0d6cc:
take a copy and clear field waiting_synchro_ before cancelling the activity
to avoid use-after-free.

Without that, waiting_synchro_ may be free'd too early, e.g. in SleepImpl::finish()
at instruction "simcall->issuer_->waiting_synchro_ = nullptr;"

src/kernel/actor/ActorImpl.cpp

index cd885a1..efe1fa4 100644 (file)
@@ -200,20 +200,13 @@ void ActorImpl::exit()
   exception_          = nullptr;
 
   /* destroy the blocking synchro if any */
-  if (waiting_synchro_ != nullptr) {
-    waiting_synchro_->cancel();
-    waiting_synchro_->set_state(activity::State::FAILED);
-
-    if (auto exec = boost::dynamic_pointer_cast<activity::ExecImpl>(waiting_synchro_)) {
-      exec->clean_action();
-    } else if (auto comm = boost::dynamic_pointer_cast<activity::CommImpl>(waiting_synchro_)) {
-      comm->unregister_simcall(&simcall_);
-    } else {
-      activity::ActivityImplPtr(waiting_synchro_)->finish();
-    }
-
+  if (auto activity = waiting_synchro_) {
     activities_.remove(waiting_synchro_);
     waiting_synchro_ = nullptr;
+
+    activity->cancel();
+    activity->set_state(activity::State::FAILED);
+    activity->post();
   }
   for (auto const& activity : activities_)
     activity->cancel();