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/event_loop.h b/aos/events/event_loop.h
index 3ecd93f..3ceb240 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -862,6 +862,28 @@
   absl::btree_set<const Channel *> taken_watchers_, taken_senders_;
 };
 
+// Interface for terminating execution of an EventLoop.
+//
+// Prefer this over binding a lambda to an Exit() method when passing ownership
+// in complicated ways because implementations should have assertions to catch
+// it outliving the object it's referring to, instead of having a
+// use-after-free.
+//
+// This is not exposed by EventLoop directly because different EventLoop
+// implementations provide this functionality at different scopes, or possibly
+// not at all.
+class ExitHandle {
+ public:
+  ExitHandle() = default;
+  virtual ~ExitHandle() = default;
+
+  // Exits some set of event loops. Details depend on the implementation.
+  //
+  // This means no more events will be processed, but any currently being
+  // processed will finish.
+  virtual void Exit() = 0;
+};
+
 }  // namespace aos
 
 #include "aos/events/event_loop_tmpl.h"  // IWYU pragma: export