Pass the EventLoopRuntime by value

Now that the EventLoopRuntime simply wraps a &CppEventLoopRuntime,
we can make give the spawned task an owned EventLoopRuntime. This means
that the spawned future can now own and use the EventLoopRuntime within it.
This is safe because as long as the EventLoop exists, so does the
CppEventLoopRuntime.

Change-Id: Iccaa6373fdb9d61a7995758f7b99906275f18c99
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/event_loop_runtime.rs b/aos/events/event_loop_runtime.rs
index 461f650..dfd206e 100644
--- a/aos/events/event_loop_runtime.rs
+++ b/aos/events/event_loop_runtime.rs
@@ -236,7 +236,7 @@
     /// ```
     pub fn new<F>(event_loop: T, fun: F) -> Self
     where
-        F: for<'event_loop> FnOnce(&mut EventLoopRuntime<'event_loop>),
+        F: for<'event_loop> FnOnce(EventLoopRuntime<'event_loop>),
     {
         // SAFETY: The EventLoopRuntime never escapes this function, which means the only code that
         // observes its lifetime is `fun`. `fun` must be generic across any value of its
@@ -253,8 +253,8 @@
         // `EventLoopHolder`s safety requirements prevent anybody else from touching the underlying
         // `aos::EventLoop`.
         let cpp_runtime = unsafe { CppEventLoopRuntime::new(event_loop.into_raw()).within_box() };
-        let mut runtime = unsafe { EventLoopRuntime::new(&cpp_runtime) };
-        fun(&mut runtime);
+        let runtime = unsafe { EventLoopRuntime::new(&cpp_runtime) };
+        fun(runtime);
         Self(ManuallyDrop::new(cpp_runtime), PhantomData)
     }
 }
@@ -271,6 +271,7 @@
     }
 }
 
+#[derive(Copy, Clone)]
 pub struct EventLoopRuntime<'event_loop>(
     &'event_loop CppEventLoopRuntime,
     // See documentation of [`new`] for details.
diff --git a/aos/events/ping.rs b/aos/events/ping.rs
index e85ae06..d9673fa 100644
--- a/aos/events/ping.rs
+++ b/aos/events/ping.rs
@@ -28,7 +28,7 @@
     let ping = PingTask::new();
     ShmEventLoop::new(&config).run_with(|runtime| {
         runtime.set_realtime_priority(5);
-        runtime.spawn(ping.tasks(runtime, app.sleep));
+        runtime.spawn(ping.tasks(*runtime, app.sleep));
     });
 }
 
@@ -45,8 +45,8 @@
     }
 
     /// Returns a future with all the tasks for the ping process
-    pub async fn tasks(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never {
-        futures::join!(self.ping(event_loop, sleep), self.handle_pong(event_loop));
+    pub async fn tasks(&self, event_loop: EventLoopRuntime<'_>, sleep: u64) -> Never {
+        futures::join!(self.ping(&event_loop, sleep), self.handle_pong(&event_loop));
         unreachable!("Let's hope `never_type` gets stabilized soon :)");
     }
 
diff --git a/aos/events/pong.rs b/aos/events/pong.rs
index d030dc7..34da238 100644
--- a/aos/events/pong.rs
+++ b/aos/events/pong.rs
@@ -19,14 +19,14 @@
     aos_init::init();
     let config = config::read_config_from(Path::new("pingpong_config.json")).unwrap();
     ShmEventLoop::new(&config).run_with(|runtime| {
-        let task = pong(runtime);
+        let task = pong(*runtime);
         runtime.set_realtime_priority(5);
         runtime.spawn(task);
     });
 }
 
 /// Responds to ping messages with an equivalent pong.
-async fn pong(event_loop: &EventLoopRuntime<'_>) -> Never {
+async fn pong(event_loop: EventLoopRuntime<'_>) -> Never {
     // The watcher gives us incoming ping messages.
     let mut ping_watcher: Watcher<ping::Ping> = event_loop.make_watcher("/test").unwrap();
 
diff --git a/aos/events/shm_event_loop.rs b/aos/events/shm_event_loop.rs
index cd611da..ee6df18 100644
--- a/aos/events/shm_event_loop.rs
+++ b/aos/events/shm_event_loop.rs
@@ -165,9 +165,7 @@
     /// ```
     pub fn run_with<'env, F>(mut self, fun: F)
     where
-        F: for<'event_loop> FnOnce(
-            &'event_loop mut Scoped<'event_loop, 'env, EventLoopRuntime<'event_loop>>,
-        ),
+        F: for<'event_loop> FnOnce(Scoped<'event_loop, 'env, EventLoopRuntime<'event_loop>>),
     {
         // SAFETY: The runtime and the event loop (i.e. self) both get destroyed at the end of this
         // scope: first the runtime followed by the event loop. The runtime gets exclusive access
@@ -175,8 +173,8 @@
         let cpp_runtime =
             unsafe { CppEventLoopRuntime::new(self.inner.as_mut().event_loop_mut()).within_box() };
         let runtime = unsafe { EventLoopRuntime::new(&cpp_runtime) };
-        let mut runtime = Scoped::new(runtime);
-        fun(&mut runtime);
+        let runtime = Scoped::new(runtime);
+        fun(runtime);
         self.run();
     }
 
@@ -201,6 +199,7 @@
 /// any `'scope`, this allows the compiler to propagate lifetime bounds which
 /// outlive any of the possible `'scope`. This is the simplest way to express
 /// this concept to the compiler right now.
+#[derive(Clone, Copy)]
 pub struct Scoped<'scope, 'env: 'scope, T: 'scope> {
     data: T,
     _env: PhantomData<fn(&'env ()) -> &'env ()>,
@@ -266,7 +265,7 @@
                 let mut event_loop = ShmEventLoop::new(config);
                 let exit_handle = event_loop.make_exit_handle();
                 event_loop.run_with(|runtime| {
-                    runtime.spawn(async {
+                    runtime.spawn(async move {
                         let mut watcher: Watcher<ping::Ping> = runtime
                             .make_watcher("/test")
                             .expect("Can't create `Ping` watcher");
@@ -283,7 +282,7 @@
                 let mut event_loop = ShmEventLoop::new(config);
                 let exit_handle = event_loop.make_exit_handle();
                 event_loop.run_with(|runtime| {
-                    runtime.spawn(async {
+                    runtime.spawn(async move {
                         let mut sender: Sender<ping::Ping> = runtime
                             .make_sender("/test")
                             .expect("Can't create `Ping` sender");
diff --git a/aos/events/simulated_event_loop.rs b/aos/events/simulated_event_loop.rs
index 96c4e7e..e050893 100644
--- a/aos/events/simulated_event_loop.rs
+++ b/aos/events/simulated_event_loop.rs
@@ -91,7 +91,7 @@
         fun: F,
     ) -> EventLoopRuntimeHolder<SimulatedEventLoopHolder>
     where
-        F: for<'event_loop> FnOnce(&mut EventLoopRuntime<'event_loop>),
+        F: for<'event_loop> FnOnce(EventLoopRuntime<'event_loop>),
     {
         let event_loop = self.make_event_loop(name, node);
         // SAFETY: We just created this EventLoop, so we are the exclusive owner of it.