Create an ExitHandle interface

This is a safer alternative to our existing pattern of capturing the
pointer in a lambda, and it's more Rust-friendly.

Change-Id: Id0f3fe5a2badcf1a4ae871d0cc7c3ff48d1c22f8
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/aos/events/shm_event_loop.h b/aos/events/shm_event_loop.h
index e51f21b..425d334 100644
--- a/aos/events/shm_event_loop.h
+++ b/aos/events/shm_event_loop.h
@@ -22,6 +22,7 @@
 class ShmSender;
 class SimpleShmFetcher;
 class ShmFetcher;
+class ShmExitHandle;
 
 }  // namespace shm_event_loop_internal
 
@@ -48,6 +49,8 @@
   // Exits the event loop.  Async safe.
   void Exit();
 
+  std::unique_ptr<ExitHandle> MakeExitHandle();
+
   aos::monotonic_clock::time_point monotonic_now() const override {
     return aos::monotonic_clock::now();
   }
@@ -138,6 +141,7 @@
   friend class shm_event_loop_internal::ShmSender;
   friend class shm_event_loop_internal::SimpleShmFetcher;
   friend class shm_event_loop_internal::ShmFetcher;
+  friend class shm_event_loop_internal::ShmExitHandle;
 
   using EventLoop::SendTimingReport;
 
@@ -165,6 +169,8 @@
 
   const UUID boot_uuid_;
 
+  int exit_handle_count_ = 0;
+
   // Capture the --shm_base flag at construction time.  This makes it much
   // easier to make different shared memory regions for doing things like
   // multi-node tests.