Fix recursion of AllowApplicationCreationDuring in LogReader
Change-Id: I051e7e687b6c06c9bc04bff35ec5ec9db9ba6bc1
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/event_scheduler.cc b/aos/events/event_scheduler.cc
index 115b2c7..ae50917 100644
--- a/aos/events/event_scheduler.cc
+++ b/aos/events/event_scheduler.cc
@@ -459,6 +459,10 @@
}
void EventSchedulerScheduler::TemporarilyStopAndRun(std::function<void()> fn) {
+ if (in_on_run_) {
+ LOG(FATAL)
+ << "Can't call AllowApplicationCreationDuring from an OnRun callback.";
+ }
const bool was_running = is_running_;
if (is_running_) {
is_running_ = false;
@@ -475,11 +479,13 @@
for (EventScheduler *scheduler : schedulers_) {
scheduler->MaybeRunOnStartup();
}
+ in_on_run_ = true;
// We must trigger all the OnRun's *after* all the OnStartup callbacks are
// triggered because that is the contract that we have stated.
for (EventScheduler *scheduler : schedulers_) {
scheduler->MaybeRunOnRun();
}
+ in_on_run_ = false;
}
} // namespace aos
diff --git a/aos/events/event_scheduler.h b/aos/events/event_scheduler.h
index 848a1cf..55fa9a4 100644
--- a/aos/events/event_scheduler.h
+++ b/aos/events/event_scheduler.h
@@ -357,6 +357,8 @@
// True if we are running.
bool is_running_ = false;
+
+ bool in_on_run_ = false;
// The current time.
distributed_clock::time_point now_ = distributed_clock::epoch();
// List of schedulers to run in sync.
diff --git a/aos/events/logging/log_reader.h b/aos/events/logging/log_reader.h
index bb3588a..d36db70 100644
--- a/aos/events/logging/log_reader.h
+++ b/aos/events/logging/log_reader.h
@@ -517,9 +517,18 @@
const monotonic_clock::time_point start_time =
monotonic_start_time(boot_count());
if (start_time == monotonic_clock::min_time) {
- LOG(ERROR)
- << "No start time, skipping, please figure out when this happens";
- NotifyLogfileStart();
+ if (event_loop_->node()) {
+ LOG(ERROR) << "No start time for "
+ << event_loop_->node()->name()->string_view()
+ << ", skipping.";
+ } else {
+ LOG(ERROR) << "No start time, skipping.";
+ }
+
+ // This is called from OnRun. There is too much complexity in supporting
+ // OnStartup callbacks from inside OnRun. Instead, schedule a timer for
+ // "now", and have that do what we need.
+ startup_timer_->Schedule(event_loop_->monotonic_now());
return;
}
if (node_event_loop_factory_) {
diff --git a/aos/events/simulated_event_loop_test.cc b/aos/events/simulated_event_loop_test.cc
index 0afa22e..23badae 100644
--- a/aos/events/simulated_event_loop_test.cc
+++ b/aos/events/simulated_event_loop_test.cc
@@ -2101,6 +2101,18 @@
"All ExitHandles must be destroyed before the factory");
}
+// Test that AllowApplicationCreationDuring can't happen in OnRun callbacks.
+TEST(SimulatedEventLoopDeathTest, AllowApplicationCreationDuringInOnRun) {
+ aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+ aos::configuration::ReadConfig(
+ ArtifactPath("aos/events/multinode_pingpong_test_split_config.json"));
+ auto factory = std::make_unique<SimulatedEventLoopFactory>(&config.message());
+ NodeEventLoopFactory *pi1 = factory->GetNodeEventLoopFactory("pi1");
+ std::unique_ptr<EventLoop> loop = pi1->MakeEventLoop("foo");
+ loop->OnRun([&]() { factory->AllowApplicationCreationDuring([]() {}); });
+ EXPECT_DEATH(factory->RunFor(chrono::seconds(1)), "OnRun");
+}
+
// Tests that messages don't survive a reboot of a node.
TEST(SimulatedEventLoopTest, ChannelClearedOnReboot) {
aos::FlatbufferDetachedBuffer<aos::Configuration> config =