From e62adea1f93f8eaba2f9da5ebe90e5f23a480101 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Thu, 18 Dec 2025 09:57:52 +0100 Subject: executor: Add fallible from_waker getter --- embassy-executor/src/raw/mod.rs | 6 ++++++ embassy-executor/src/raw/waker.rs | 13 +++++++++---- embassy-executor/src/raw/waker_turbo.rs | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'embassy-executor/src') diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index ab845ed3b..2b7560de6 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -49,6 +49,7 @@ use self::run_queue::{RunQueue, RunQueueItem}; use self::state::State; use self::util::{SyncUnsafeCell, UninitCell}; pub use self::waker::task_from_waker; +use self::waker::try_task_from_waker; use super::SpawnToken; use crate::{Metadata, SpawnError}; @@ -57,6 +58,11 @@ extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static unsafe { task_from_waker(waker).timer_queue_item() } } +#[unsafe(no_mangle)] +extern "Rust" fn __try_embassy_time_queue_item_from_waker(waker: &Waker) -> Option<&'static mut TimerQueueItem> { + unsafe { try_task_from_waker(waker).map(|task| task.timer_queue_item()) } +} + /// Raw task header for use in task pointers. /// /// A task can be in one of the following states: diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs index 2706f0fdf..8416f9f93 100644 --- a/embassy-executor/src/raw/waker.rs +++ b/embassy-executor/src/raw/waker.rs @@ -32,13 +32,18 @@ pub(crate) unsafe fn from_task(p: TaskRef) -> Waker { /// /// Panics if the waker is not created by the Embassy executor. pub fn task_from_waker(waker: &Waker) -> TaskRef { + unwrap!( + try_task_from_waker(waker), + "Found waker not created by the Embassy executor. Unless the generic timer queue is enabled, `embassy_time::Timer` only works with the Embassy executor." + ) +} + +pub(crate) fn try_task_from_waker(waker: &Waker) -> Option { // make sure to compare vtable addresses. Doing `==` on the references // will compare the contents, which is slower. if waker.vtable() as *const _ != &VTABLE as *const _ { - panic!( - "Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor." - ) + return None; } // safety: our wakers are always created with `TaskRef::as_ptr` - unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) } + Some(unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) }) } diff --git a/embassy-executor/src/raw/waker_turbo.rs b/embassy-executor/src/raw/waker_turbo.rs index 919bcc61a..ee33e7633 100644 --- a/embassy-executor/src/raw/waker_turbo.rs +++ b/embassy-executor/src/raw/waker_turbo.rs @@ -25,6 +25,10 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef { unsafe { TaskRef::from_ptr(ptr as *const TaskHeader) } } +pub(crate) fn try_task_from_waker(waker: &Waker) -> Option { + Some(task_from_waker(waker)) +} + #[inline(never)] #[unsafe(no_mangle)] fn _turbo_wake(ptr: NonNull<()>) { -- cgit