diff options
| -rw-r--r-- | embassy-executor/src/spawner.rs | 18 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/self_spawn_current_executor.rs | 3 |
2 files changed, 19 insertions, 2 deletions
diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 522d97db3..2909d19a0 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs | |||
| @@ -122,10 +122,26 @@ impl Spawner { | |||
| 122 | /// This function is `async` just to get access to the current async | 122 | /// This function is `async` just to get access to the current async |
| 123 | /// context. It returns instantly, it does not block/yield. | 123 | /// context. It returns instantly, it does not block/yield. |
| 124 | /// | 124 | /// |
| 125 | /// Using this method is discouraged due to it being unsafe. Consider the following | ||
| 126 | /// alternatives instead: | ||
| 127 | /// | ||
| 128 | /// - Pass the initial `Spawner` as an argument to tasks. Note that it's `Copy`, so you can | ||
| 129 | /// make as many copies of it as you want. | ||
| 130 | /// - Use `SendSpawner::for_current_executor()` instead, which is safe but can only be used | ||
| 131 | /// if task arguments are `Send`. | ||
| 132 | /// | ||
| 133 | /// The only case where using this method is absolutely required is obtaining the `Spawner` | ||
| 134 | /// for an `InterruptExecutor`. | ||
| 135 | /// | ||
| 136 | /// # Safety | ||
| 137 | /// | ||
| 138 | /// You must only execute this with an async `Context` created by the Embassy executor. | ||
| 139 | /// You must not execute it with manually-created `Context`s. | ||
| 140 | /// | ||
| 125 | /// # Panics | 141 | /// # Panics |
| 126 | /// | 142 | /// |
| 127 | /// Panics if the current executor is not an Embassy executor. | 143 | /// Panics if the current executor is not an Embassy executor. |
| 128 | pub fn for_current_executor() -> impl Future<Output = Self> { | 144 | pub unsafe fn for_current_executor() -> impl Future<Output = Self> { |
| 129 | poll_fn(|cx| { | 145 | poll_fn(|cx| { |
| 130 | let task = raw::task_from_waker(cx.waker()); | 146 | let task = raw::task_from_waker(cx.waker()); |
| 131 | let executor = unsafe { | 147 | let executor = unsafe { |
diff --git a/examples/nrf52840/src/bin/self_spawn_current_executor.rs b/examples/nrf52840/src/bin/self_spawn_current_executor.rs index ec9569a64..ddb40dc53 100644 --- a/examples/nrf52840/src/bin/self_spawn_current_executor.rs +++ b/examples/nrf52840/src/bin/self_spawn_current_executor.rs | |||
| @@ -10,7 +10,8 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 10 | async fn my_task(n: u32) { | 10 | async fn my_task(n: u32) { |
| 11 | Timer::after_secs(1).await; | 11 | Timer::after_secs(1).await; |
| 12 | info!("Spawning self! {}", n); | 12 | info!("Spawning self! {}", n); |
| 13 | unwrap!(Spawner::for_current_executor().await.spawn(my_task(n + 1))); | 13 | let spawner = unsafe { Spawner::for_current_executor().await }; |
| 14 | unwrap!(spawner.spawn(my_task(n + 1))); | ||
| 14 | } | 15 | } |
| 15 | 16 | ||
| 16 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
